From 8e83db885328ce09a2d05017daf3f2b098a29a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Wed, 25 Sep 2024 11:04:33 +0200 Subject: [PATCH 1/5] feat(tx-builder): move necessary icons to transaction builder --- .../src/assets/fonts/DMSans700.woff2 | Bin 0 -> 23328 bytes .../src/assets/fonts/DMSansRegular.woff2 | Bin 0 -> 23636 bytes .../FixedIcon/images/arrowReceived.tsx | 13 ++ .../FixedIcon/images/arrowReceivedWhite.tsx | 13 ++ .../components/FixedIcon/images/arrowSent.tsx | 13 ++ .../FixedIcon/images/arrowSentWhite.tsx | 13 ++ .../components/FixedIcon/images/arrowSort.tsx | 13 ++ .../components/FixedIcon/images/bullit.tsx | 13 ++ .../FixedIcon/images/chevronDown.tsx | 13 ++ .../FixedIcon/images/chevronLeft.tsx | 13 ++ .../FixedIcon/images/chevronRight.tsx | 13 ++ .../components/FixedIcon/images/chevronUp.tsx | 13 ++ .../FixedIcon/images/connectedRinkeby.tsx | 12 ++ .../FixedIcon/images/connectedWallet.tsx | 12 ++ .../FixedIcon/images/creatingInProgress.tsx | 16 ++ .../FixedIcon/images/dropdownArrowSmall.tsx | 12 ++ .../FixedIcon/images/networkError.tsx | 26 +++ .../FixedIcon/images/notConnected.tsx | 18 ++ .../components/FixedIcon/images/notOwner.tsx | 34 +++ .../components/FixedIcon/images/options.tsx | 13 ++ .../src/components/FixedIcon/images/plus.tsx | 13 ++ .../FixedIcon/images/settingsChange.tsx | 13 ++ .../components/FixedIcon/images/threeDots.tsx | 13 ++ .../src/components/FixedIcon/index.tsx | 63 ++++++ .../src/components/Icon/images/add.tsx | 36 ++++ .../components/Icon/images/addressBook.tsx | 28 +++ .../components/Icon/images/addressBookAdd.tsx | 26 +++ .../src/components/Icon/images/alert.tsx | 34 +++ .../src/components/Icon/images/allowances.tsx | 26 +++ .../src/components/Icon/images/apps.tsx | 40 ++++ .../src/components/Icon/images/arrowDown.tsx | 26 +++ .../src/components/Icon/images/arrowLeft.tsx | 38 ++++ .../src/components/Icon/images/arrowRight.tsx | 38 ++++ .../src/components/Icon/images/arrowUp.tsx | 38 ++++ .../src/components/Icon/images/assets.tsx | 36 ++++ .../Icon/images/awaitingConfirmations.tsx | 34 +++ .../src/components/Icon/images/bookmark.tsx | 30 +++ .../components/Icon/images/bookmarkFilled.tsx | 30 +++ .../src/components/Icon/images/camera.tsx | 37 ++++ .../src/components/Icon/images/chain.tsx | 38 ++++ .../src/components/Icon/images/check.tsx | 26 +++ .../components/Icon/images/circleCheck.tsx | 38 ++++ .../components/Icon/images/circleCross.tsx | 36 ++++ .../components/Icon/images/circleDropdown.tsx | 36 ++++ .../src/components/Icon/images/code.tsx | 27 +++ .../components/Icon/images/collectibles.tsx | 38 ++++ .../src/components/Icon/images/copy.tsx | 28 +++ .../src/components/Icon/images/cross.tsx | 26 +++ .../src/components/Icon/images/currency.tsx | 30 +++ .../src/components/Icon/images/delete.tsx | 30 +++ .../components/Icon/images/devicePassword.tsx | 38 ++++ .../src/components/Icon/images/edit.tsx | 26 +++ .../src/components/Icon/images/error.tsx | 40 ++++ .../src/components/Icon/images/eth.tsx | 26 +++ .../src/components/Icon/images/export.tsx | 36 ++++ .../components/Icon/images/externalLink.tsx | 36 ++++ .../src/components/Icon/images/eye.tsx | 34 +++ .../src/components/Icon/images/eyeOff.tsx | 30 +++ .../components/Icon/images/filledCross.tsx | 26 +++ .../components/Icon/images/fingerPrint.tsx | 46 ++++ .../components/Icon/images/fuelIndicator.tsx | 42 ++++ .../src/components/Icon/images/getInTouch.tsx | 26 +++ .../src/components/Icon/images/gift.tsx | 72 +++++++ .../src/components/Icon/images/home.tsx | 28 +++ .../src/components/Icon/images/import.tsx | 36 ++++ .../src/components/Icon/images/info.tsx | 40 ++++ .../src/components/Icon/images/knowledge.tsx | 26 +++ .../src/components/Icon/images/licenses.tsx | 34 +++ .../src/components/Icon/images/loadSafe.tsx | 26 +++ .../src/components/Icon/images/locked.tsx | 34 +++ .../components/Icon/images/mobileConfirm.tsx | 34 +++ .../src/components/Icon/images/noInternet.tsx | 34 +++ .../src/components/Icon/images/owners.tsx | 26 +++ .../src/components/Icon/images/paste.tsx | 28 +++ .../components/Icon/images/paymentToken.tsx | 28 +++ .../components/Icon/images/privacyPolicy.tsx | 28 +++ .../src/components/Icon/images/qrCode.tsx | 78 +++++++ .../src/components/Icon/images/question.tsx | 39 ++++ .../src/components/Icon/images/rateApp.tsx | 26 +++ .../src/components/Icon/images/received.tsx | 36 ++++ .../src/components/Icon/images/recover.tsx | 38 ++++ .../components/Icon/images/replaceOwner.tsx | 26 +++ .../Icon/images/requiredConfirmations.tsx | 30 +++ .../src/components/Icon/images/restricted.tsx | 26 +++ .../src/components/Icon/images/resync.tsx | 26 +++ .../src/components/Icon/images/rocket.tsx | 28 +++ .../src/components/Icon/images/safe.tsx | 39 ++++ .../src/components/Icon/images/scan.tsx | 30 +++ .../src/components/Icon/images/search.tsx | 26 +++ .../src/components/Icon/images/sendAgain.tsx | 38 ++++ .../src/components/Icon/images/sent.tsx | 36 ++++ .../components/Icon/images/serverError.tsx | 34 +++ .../src/components/Icon/images/settings.tsx | 26 +++ .../components/Icon/images/settingsChange.tsx | 36 ++++ .../components/Icon/images/settingsTool.tsx | 28 +++ .../src/components/Icon/images/share.tsx | 27 +++ .../src/components/Icon/images/termsOfUse.tsx | 26 +++ .../Icon/images/transactionsInactive.tsx | 26 +++ .../src/components/Icon/images/unlocked.tsx | 34 +++ .../src/components/Icon/images/userEdit.tsx | 26 +++ .../src/components/Icon/images/wallet.tsx | 28 +++ apps/tx-builder/src/components/Icon/index.tsx | 204 ++++++++++++++++++ .../src/components/IconText/index.tsx | 73 +++++++ 103 files changed, 3195 insertions(+) create mode 100644 apps/tx-builder/src/assets/fonts/DMSans700.woff2 create mode 100644 apps/tx-builder/src/assets/fonts/DMSansRegular.woff2 create mode 100644 apps/tx-builder/src/components/FixedIcon/images/arrowReceived.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/arrowReceivedWhite.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/arrowSent.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/arrowSentWhite.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/arrowSort.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/bullit.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/chevronDown.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/chevronLeft.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/chevronRight.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/chevronUp.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/connectedRinkeby.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/connectedWallet.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/creatingInProgress.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/dropdownArrowSmall.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/networkError.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/notConnected.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/notOwner.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/options.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/plus.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/settingsChange.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/images/threeDots.tsx create mode 100644 apps/tx-builder/src/components/FixedIcon/index.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/add.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/addressBook.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/alert.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/allowances.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/apps.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/arrowDown.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/arrowLeft.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/arrowRight.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/arrowUp.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/assets.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/bookmark.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/camera.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/chain.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/check.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/circleCheck.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/circleCross.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/circleDropdown.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/code.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/collectibles.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/copy.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/cross.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/currency.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/delete.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/devicePassword.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/edit.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/error.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/eth.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/export.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/externalLink.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/eye.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/eyeOff.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/filledCross.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/fingerPrint.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/getInTouch.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/gift.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/home.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/import.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/info.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/knowledge.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/licenses.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/loadSafe.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/locked.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/noInternet.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/owners.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/paste.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/paymentToken.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/qrCode.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/question.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/rateApp.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/received.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/recover.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/replaceOwner.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/restricted.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/resync.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/rocket.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/safe.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/scan.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/search.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/sendAgain.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/sent.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/serverError.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/settings.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/settingsChange.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/settingsTool.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/share.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/termsOfUse.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/unlocked.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/userEdit.tsx create mode 100644 apps/tx-builder/src/components/Icon/images/wallet.tsx create mode 100644 apps/tx-builder/src/components/Icon/index.tsx create mode 100644 apps/tx-builder/src/components/IconText/index.tsx diff --git a/apps/tx-builder/src/assets/fonts/DMSans700.woff2 b/apps/tx-builder/src/assets/fonts/DMSans700.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4b0a5ded0027ca1fa373d1375c1bf251ada151c9 GIT binary patch literal 23328 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 literal 0 HcmV?d00001 diff --git a/apps/tx-builder/src/assets/fonts/DMSansRegular.woff2 b/apps/tx-builder/src/assets/fonts/DMSansRegular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..21f9cbc2b4a5a5016f64bebbacf2f93cfa975ccb GIT binary patch literal 23636 zcmZ^~W6&@>&@Oh{ww~LzZQHhO+qP}nwr$(CjlQS-+L@kC_fIgBjdrgjS7zPhL>U19 z0sa$hWdOwgm7a+M0BGI)Uv>Yh{QnlL08Z>vdYm9)Fnxe9bqIaPY#2lcsK6xZfM+S_ z5N7~DRv=>FC}|LU&|quuI4zg}9_-mAv*GBgS1|x*GI6UH&uct(q=c;q)6o|?i@}(J zuoz(OaXXf;zrVkxq|oscEs9*-CQ+p_WQsjYsM@a&!W}JJrmpar!f)W z)}+9qZQd5SKfYwSu#^_~#tN=bMo_<^Rh1d1j8_-r0QC@u=5d+@_9oTZ5ZdO$4ZQ)j zM`3u6Hs=M>w=)gc4B3-IDr@Z^(N)fuNBC|(p5IL~T~Y+9c3_2p>tHxhvNnkj_yah( zt?#$n*dvGre(7Nln`&4Wri6>i@RSJ2;udps)Z3}XWfiTd{uHN$)Bd`@ze>%w-e+Kb z2l5RK1Q{8q2)N4TYVznb@X)H65_nd5ogM<%d#BAXMTmGT<^Yg~@N=ohT(N5s;#e|- z=8;PIGSg_xn{%1X+G&u}pMPscg*(0)XFEA=rzi{R>Mz#*Ceg9-22-?xKo{-eZ~U+S zB>aT9TYh#Ox8dPN5&j7=ib&SG_&GlL5F-r0KLH1tOZRGvnA|eAZV|S+3dT`0_n4Vq zHg>nS;dVg+KFITMIV5$VoI>qYRq|1Lg|ZB#?yahpHqS1LF5b=yVFmaz2Mv|^JpQ9O zpYo4JDRrh?Z58v2(r1xm3!&cy5OH=zbGl07R}X3qcLkRHHhEb~+}r4DT`njDQq)h* zyZm+qHs+_vMtlxRwDS@15vi%gs^I_x`i+RpV%Ijn?jeEKU;@+u81{P>tD`%aP8*dF zn4@KcW6!p4A zWsS#bbafO)tCfRpDAhoV@zi9p{`f$yPcWVx?NkE?TISjZ&pTK6PGxkNv36X(t6TVEZvhStO*XILOWk|#r0TD5w>EUnv+Mqhh3Fg2kk!g+X zJ?j-5HphjlrIy&;A451fwU4YX3Lpz86^I(_U=lF+{e%qyxM<3n48m2{#{!IYT&+JZ zhztou1VS<%5~~tGSsZjR9lWv`q%D0t^=4{|5x-5nc#QD-cTK z7#l|YIr4+RV))?n9pvFqQDsqYwm5`L9$?0j((nm5`$q1kSZ~nR{MPLh{ENuwkq9fG z_u4lqLbqiqX@KKz)EoZr3*gK|8zXnl;fXy589ZhQVvw1i$-jry2*fi|xD zz30n!as$10!M^hy#ud`fM`us%EB3I=8JrlBbephyx~j$xC5J}i6y!3|kGIhBdxHsP zm~R8!>-JnMx4)^O>=|kPXqkr-@XQU#d+Xi%8Vpl|ho^=QS03WRb!foVw_FwmqtA)f z^I9(iY|h;YqwVS8??ZR?kGij{y4yoZhOgs$bJ6JC!!rn12u|}GB{3yXk2yBvAr71M|>WLQ@*RE%}OtBbk`+h6r?8?atd#dk^ z&znBO>@9K|)Z9G>b^SgR6xs(pB@QRRi=2%@;U^TKa8j)O6efY8=wrfBc*qhZ zG?5B)&h8co%u+`u{Zl6k;gXSSo5XSE(Ci!j!%oRK4tbpTDZPO9Q_f&c1wl?(|4oTT z=S$fg5+RFANu3mIn;6M}S~ikjPB8XEeg36VWqCh=^QL#D?;X#@-*VcSeFN?`e)L;;ySg|l4Sl}Xz71?FJ?ri`(jAtdJnLm<-t~3+l7b9d%{T9V5w9c@ z;uqDMeQUkCUE@t_z1m&#pb>w@LNhCw=od4%H4UrcmA&Ph3NGVw@h0XCmUc%sCexhD zN-Pd$vpHdt;wn$S#8c0cU6gXu)#=si_DhdbCrqCedFox`p8;h?ywlV)UhU787nLt{ zb$V)x8itg%G@+4GS6g+OZZ10RH?J%Pn+b%v15?X)<5?9#%eI!;NFO^NGbS>>l}Fcl z@D(zARS&ekx7}?|sg=|oYLDWU-X~L3dAb~3j+|-)Ps`*lhyVjXHvrt#mBAV-Inho-DmLR6R+ z?kQE8GR+GjctX()&D}n4zd~1Kt#f+4u70hbyCr=Lz?z?QWjCij@Vjr7w=z5Cq=?J> z%<{0(LB#=9@hlLqkzgu8qWQ?g#1s;uiAgBIf~tsB=_SS$>XwP3qEtmm3sV@z(Tp^S zZHaD)Z;9}UstaTaS?5jXQRh|VLv3xGI)%0oD^S>Y`}6FBnA?l&QYYoCliUkbJJ>oU zR_%!Vul^wTCZK?bh&ItkQSqGas^fSl_(013km5kv{AdV3k^YqV9+9^ckOGqNh{qry ziUq0(stu`%QY9s)<`9~JvH4^e5Tb%r$4SL9j~b66k1CJ1KbFBgrx)vD&nF`ug8xnmjX%`m5^tJJgCf1}-5lbj(%))&>d4+Vp8_y4}k{ zsj;~M4nBUuH^Fczx7&9MpJ%137FmCPS1QKmsj{cnRuK6bF^$f#p~kcez3cj?;q3U3 z1O>#=!h{FJj1l+>;>t)fgquP_ zxDM&;ve~4)$bAui#QKTR#rPHCSc$RW@i4;C#)KN<^2JEd^$1b*7*h2pQ}sAh^+;9q zSXT9DSM|8q^@v&WL7K}4II~AUw1-Hw^0kV#^2GuW0rC(*;s|gF1VDxS%Ham^dR?{c z#k~ayHZ2MTVjD$su1XtP zWD#;sBVyHT-_NKt`~?7D5|PK=Btn%;XF|+ju!&^UAV}DW0t{34*#7Z&{lvtCG$@=9 zd67tp3c(-|DR8y9evA`J00fXwegk_DBvhE7kpoC!qzu851x#tQtf7+!qsjGV%%%qY zIYXRCv$;>dl?u2Eb@#C@?g%AWuA^!vM0&vlb;6VhR7n+W^@-PQ$E}?5F)U`w#c#{5 z@~J)WlHA9z-EEEbF1J6Gj62k!4SoA!*jh9?d1Ct1?UWK^|ZMIud3 zPq5MQX9JV}O_z6oJaOv(sYFF{W$+7a$&K&Z`w(wU`<*3C=;Z+`UG#5FZv+4(6hurk zKOby{;aLy4xT6? zLC}03wfPc6O7& z#2H9b%(sh5{%aHMweADYeT}9mb)wb%v>Rrw@=-ivrpKzM=9tU8$)KyZ;< z%TNQa7(cu&)bOAk0l)x44g(n*%`X6(iR%+kK=a?j*}v2xleY#vt2K7g(|KdL%@~@a zwGhZ*Jo)E#GCv9-pPrbV5eSq8Bl+HPrD82#CrnnS1<1JV`Fy2p&tE`@!P;=RJfdz- zRY~^E5ds1q0w!Q^AA*8 zsNi25GAesQnf)fFSx!{HI60D3F=L0|#!N5R4!+%|hm>s>@{1~q`Es$x?rlnJJ*V4- zh-+SRuA_(f($@*P!gh^&*c(-&BBmu~+OGd(TW?JCL3;V~V%p z5(!*M^i2oB|IEe3zay~&tGmanVzuqvW`uQ%%xRj!7=CR*9h`PjEsY$TDo$oo`O-_E z+1N|)CSD!`2?sME5Q{k+7bzk++S?e8AQ+*1#j-`Srn0Q-`0%KpaACu2iMIu6i^fvT z4cT*iO|N7Zg!fc*akw_3dV(NS76C+{AHzr+Sm(b?_`IT)uj~;d2r}aT*k7O#Oh07T zHV=*`tJE0vBce5jz!>W6dp8?napvA?Dd!7T^VNKXR2y#3=QB3F`FOYja>H!x3+p;N zmj9WDFMg}lP5lyW*Np^eJv(=RIH6K`^RfZGhBaK;SRKL2jKaz^49WksuoaPMG;a?P zuKjKMDwW9Ab~DUB4LW%eY>auRxviEhvSmvSQM6|NQ7yy>+&R0qeNg=AeE{~_$nn?4 zy|%a|Q`NTO8R=dgJW1>2k>VMs`+S|MAE4s&|Bq8csN>}F6DLq8W91AOH*jd<>fxhA zkSJzo7bv%+TrPhClAQv++1i2200M#p5XfWT1PB}a-(zOx44N=>YUlRlz}!I_XwG1z znsDa-Utav^yIWh>D2%G+uBPL(6Vtxp_{MWDe}=rH@Uvu@lObH@G}YR}p)kEf1#7+k z{|DriXotT7H$=Q2*HLvhc5pq^)dn4{4lYyH!wY+ttTx}UkX@_wB+7D_<%SB zuTE`WVf?8-K&&~zZxXxdr$aWQ8^qeTXEy-b1Ki1QT!-hU>v_{~_f(-Lp*lQcSRl*l z>vYgC;^GDtI8}inW3zlq;6Yl|us~LuB~Ggro#T`Nf5$1tmuM#)hVV_V$iX z_m3yGReQ1nh?}mHexXd3&~7rXVcDOFe>$| ze09Yec_7$LVpWF>Z2cW!5iD+G@0|k9QFIg;WH%mixX`>uxI#-M&^62g4H{v_Ha$Xr zsCDGyQo@IO$_4abM-WvqE|)CkYXwSawmhCM7i{|T@rXsFhxq^if&B>NFtPlFfdc=# zZT4-NFqWmOu2y4){?BPoxm~5Zn6Hp@>TZ16K$h!y+JUa?dD6nRHyrpd=BVH+z}1z} zRS{E!8uD))z@0dG)kcNP-7wx9`0(zmtJ*N3T0boi;9SYy@~n>h1Wn6-x$~iMkaV59 ztdbl$R%niMg5;OM7V*b%!=HmlfM#V*%)bu*IBG29+5Q6CNIidkb6`A;#XC|xjrKVoB z44VMD03SZ!e~#S{SHs5jXZ#_07$$Pukk@r&Ii9C&Xu6)qO>CN7&$FLXA(o*7Qaw+E z|G}ZqVID=sN9AwaB3r6t$r8m36K=wy@)l21>3L9y{|5!Z=k-v%v#_kNV8DV5@MZ8w zBvW1-ndkxd5io#41`x%S={^5<Q|ir=R+fCRFup<`1iiJ+aQY^JsA-rEo(Z`)<0_*A0|au-crf!WREu&^ zZYam^i-SeYz1ooB-vM%7R!5+(IP3pwWv!>tm`?%mh8${}#NjIW_Y&m$30ze;zw;kK zjQVT%jzGKDHWcRA0k9+tI1tG-iI8Iba7g?EyUGRd!-q=ID6mXsQwtTWdmljARs(b& zFXrBz7JR)`-aH3I`oqy*o(Iq|6@lp7zL)ny(1-6Dm_Nf)Cr%y=O$iYNGN0`tM8994 zQp_Yh&`ZSS9P`mAJiv@J;Y&p?coHYzy}us^rSr@f5_HE5p&ri9P~1sX$<>~bzyl2@ zF^Vvj1a^5>?vNJ=CxTwz6jxW5L|0V@PaQ+0*sY^L zK&G4d%psN9z_rU-o0awN`@q>Lr=wPTu0=KEXbSuuF!tvUugjuE?9Z<6936HV&-O;{ zHUDJnb=GxL*HU3rYNi#(++!Wd`atU&00akyUCK-CYd#JTfg90HJ#?wrVF806HTT8{ z2;$7;wCKln$(+7D@pzyB(nwj;;ZvEf{;9wTG#)64(aeHn8eqe~e)M!m4IejvoZ*l} zoONA(D4LKVK#+h1R;l_t1zc6B%<)M@(=cRauXes==~s(G_)vnSwxc0LqvC8-jCxY+ zx392wWcDAE)}iV^IP=8fDP$ebU>;DDT1Js{ZS^P6{d#`=>LAYF7j|6=LJ09V06R!% zWN_dpVi*;C?%+Kr^gyyOu}G%$1tx5wP2oi8Jl0_?CZ#mfm~+!i%eW_1O@nI7&g=V} zqM45TRW{XZ+Iiy{uGeLTT@(A}8$v1#k{SzlC91ab?m$A+;K;+myIl zwEdPj?5HK9C{YG@@h#Q8Xl)v)2jQL-hwk{3WP_XY=6T9{?X+BpZ+@0pwy7h0g}3}M zP01TfFa2kx-?e2`T>&SRO$+@djXs7mvA;mO9Q`Pp@L=UmJ=DpH}y~ zxHWa8;TM$w&@&;;y!d&ig;16yKLPf<{c1<*r@Q*G$~+ z*JSfWtCORsBEk9n-){H6@^N$D>-Y0v2+zY)YdE04BYM%#Ogev+!3YuO(cBK2_0T}e zZC7^sM;t^s9tXSf^&V@SHc7bHBO3xD(}^u%s1;hu3rb1&X3-3VshAlk_h&5TK)%;vejqUCw8_E~OZzWiuGFm)uhU>+rMP8NF*-jK)d zKnNxVan$Wa#ZsTyL_iDvNZSBqm3oikrb^2n{({sA$a3h{pVI?&bL)XB85U!CcWSjG zO5VH`mFETc<%n>4$SpTKuOf22s`>`+9L{5@pGm^61HmK+1|pRje!jkV&Y| z;eLrw$yUn~*$mjORW+Yj@C|4Wdbx3+egrp0N(WKSm+OpabGTGzl$nirTbruk5qu_t zhKD?5As3TOf_fvX{jTK%*i!j`okPOnsf2)59r|Cu`me<4V;77|4gxKGK%otxVV1bZ zvn9Bbr;tD|-W+D0h9LNHU=7A(YeWgD3k|uxx1wi}cc!HyxY*i1jP`fqeWW;ij6G9q zWmbe-dALTJ3l5*$T10hmFY|-tSVpRxq9kGB{$;+zrln`B7nrN`1UitiVcXu7tGl~*oxvh+=h zf#k|~OLrN-FY5D*b3^){1s^G0xvA}Snki;u03$M+#)GDeY5mF$5jX6 zBxe)HqJYtz7i3lNqM?aZHgir$eSjs?#yVce88#U~4t2AC5eBfWFAZPyYP93g4K5|d zDx!{7Bse>Shp)6sDb>NXq`9B=V{2L7dU2~cUe=gf1B=@`-td^^GIVaqU4PVYdXM`* z{p+a7=1aV7%6me}r@F3EGepl03QZWP=1C4@nfEj5*7~8TqM>zSk9p0IQjRtC|3-ngYpoPk>9CfI)C!_&LmCr6xe( zrT~Goykt9`vD1Y9=J3TrbYjJFa~m6Up2wpKuDQzzx{kHj@!c%#M*))^QULXLJ_wlW z5J=$V#t;&8@h^wy@F*1k`sTLO7Z8kK<))xYb@k6sS-J*ph#UyV!r{=HSlgaKVs`hJ zu)OFAcmlFlYQ?KQLv(MdUj@roJUiyMo(-dwou3a$nT<_s9`b+CQHcWfmrUU2j{Xm3 z`9uMzegNu6WB^e%Ak>XG^*3(*{G}><8*TFOgJHOc0CEHn*3*=N>)zu&ZtKGG!LAdT z$YlOV_Sd-B=u7=aL;kigQP7r~;5%%B!Z_v4A1p-rnc6B4lpz&|n>Q6gxiA6Ik@AC4 z=@`>e@_q=~PtzQnD8Uf;-Xu+i5V$?W{;LzJiHVN!gZA+}q8d2)&c9$p_nCQ!s;aZb z1XO3Lvt!)FUp^3(5T5hVjh7nIOY$g9%sOZbC${yIa8|HyUg=y`L;b`1izeanC@-DLsUu@!_r3_=;B~7Ppkf4r zM`SEjRcT)?wrB*=NpiV8%AzvSkB=D+tq}b<3*Cj92IdAo7IFQtAd>4>(UsNj^$7~m;9KHnybC< z#Fc)3!BPhekl4ean*<%*>`u09<0vZ#n7|W=YOhb|&_qxcUGO-UG7R#|<(k?8gdqi1BC)<;HF^@A38HD-0%g}BWeZ(H3B#Nwb@?L&WZ2+91|ZD{0oGy- zAV|2ijdrfjA6LOdB(Ds^cP*!svxDsZANdfdpyc8Rl*`bkH6!EhsJji)r)FiV1}|6= z&4V7&k0Bx9tBCgycuH8+N&G25GqnDW#i&+^iDCkg4a6a`8}cYqqfInn$~oaLKC8-! zjybmkRu97`^YGfiy1}G05Adh`E(kWT+gQz?VxsKDtXQM7v&pr6=|_Z!sM}U?2l)qx z!xxesJI#n++)YyRBod<=+tXiVm?+=SNKAfjuV>{wuFds1&MA_2Mcp8ixqPR+3Djlt z-ctTTjS6Z~+wG&W-h!O|sycX>Km9oddx-~d9!ZMLBrLCh!$BoOW2T76n zV_oeYfns^Be<|zA-Fk)`;Mo|(GJa<#mX(vJ(NmWMsC5&U~Xa|Ty={X84 zpJ6(`w?sY3?Y9@xiG2JXo&Pb6B@iwX--V`nMlawcs!CGH0W?vD={hDJggygg7OrMR z>_=|JUy(nvE1Uuwxj?mZ3R~9tIgn-u;`_rN4rCl1YR`eGw5M8PVhh=u9smhs00B^i zQ^TSmpBh>V_bkq+;d@#uuX~!a4)ICAVmZV=rs8CM$gM=|f2)ai(~jlUvy2S= zttfwT!(stt{z;~Kpn*#(?iQ|AXN4!77q03q?qiyq!ahO&0HD|nA+bM?uc^-rxj207 z_DD?+c7ReW8nukxY?VzcN~^_&KUga6M5e5)hyZRfZ!>u&(_NCd9`#cN-_NYk6sXyt zB@fDi>4!&_R%VK;!B(dG4#2Aml5s#Ebq!a*e@j{@-LUZ9N$|r zZFcf@z6~+Uj5$u8Jau1czkbfYyUQyy2?1*FHwoSmxt9k@_kZ6Z6G{Rqi7bbovkAR( zrJ|EMGhh@pmGuHlAcl3rMFy`t-uQp3t$T?U`5bqWurT5>oj zmu399TAyaKjn5iC&o0g>bBA`V?0+eY{93>3>mDYXx!KA&#&r5Pp7Y)^2?TM^T!r!| z0XeyVjkj@ll)z4tqVtru6Yp!Nd#@5gr^=}BRU_#^rI#LzN~DE}xi~GGg?digqo@y& zpp8~_f;9YYUHHAG@JPZ_lApaASEITtxo3c|2 z`Q`fY9QkK|*5c-w*|ZcB;wsdVVF;UjKPFTFPl7m1@q0=-z4vZ3qW8Y!eM8-iBixiu zFhs4bkEut`l3IPQ-dc@!G--?0x9KFp)w%kKCd@6nzJ58~wOCQU}yb51peIN4{i;HPpqNP*VSF?5jmC79L248ElGpK^qEB53nk0q5QPM2VNTetfVC6ug<0v5{6 z=o&FXObm9rSd~lpDo4rTe0r6^CpD#7la z%AXdfl%Q$s9VG)-7ap*o&~n#s%)~z&mKUyVS?09Fp@P1#==C{$lR(~$#cR|66kWKN zVscQ>oirD|{SZ{FUyi$*rj0*C4>aBMl`|j-^c(GVG`~mNswHDDpI*`2_M)FhuDM`x zDv~~NDfu%(9z$27%vUzgbWGNCP!oB^RnWplArcAd2&f)05gm#g ziPTcw%MSp`QsM9v#TlJEk=D>t={?t+z^oE04OS7?)zgx#GhC7}@xex!GAAS`O2zB_;#tmsj?03P<6~m+>&Sg1N!twlGRRHoyJ3 zd?!p4cDzilT}4Hf6lyX~kCzS@3NdB#Sv0?>afegI;kN7rzFNvPc20HPaZaVtD z{D;g`#Y{QHY;!*+WvRdUr4z(^pdg$iIRC7LLo7|og#z;S{LsTSoh?E5?b3FFI<85J z;00#S+ZGqg3VSzltLreOzWN5J+>_9x z+(?40NG^ko>#NXaWSvVx-_*5r3@qnpN&ZNkiP_NlF@&v)zVmTc_{I#QX4Wz_fOr0E z1pBi*-?=l&RB$8Yo?K%2{n}Ps__RPl4G-G9JnVqpfXShCW2@wfh} zYuF0v;qJ8`WXr5D+Uhk>6t$(sqVCbNTdDlZEk@i*elT63%~NaP%H1p_{07%g@Y#Y~ zf7GE-{)z(SZBQ}h0`Ri81`)iJN5NDJHDHG$)s5tfiU`U2rEMWJou4w&$?T69y=FiX zpysC^H*(|Wb2z*;Pa%X`2G9Gpr?hM(yay9k`6bLG5r)sZbI&AZobJ;Hya` zdv-03(wC0fgj+ksE4RveKA>#^9Rm7Fp0?lRvRN&w{bRY1z@1?!XKC9Q@@5TwU@nJN zhC;DxpE~VErR5V>3DYz|Sf^ZLRv1#j>n6x=`QO)?>AIrChuP@M>PS<`Sdw@zij#id~cN{m}_ek%m^NbP#ng>~nBo|D5u1`elu7tv%~Cb0?yNJ~f*{ zvM1GxC&x3MZQ|%l`T3o&tUaYI_1Gj9i6#76A3dDcEM_dB{Ry8rGIloTeI}~+wd;*- zzBYxpk$_-5fQ;ipx`dv_r5fr`ClEA_?-3-H%p}`AeSo|1V~4eW_N3qI6jb)X9{}4} zH4<;_r8FNc#sP&-x$|x1)DCz7(v0b(kh_DEx*k!#!KwaLHkYuzj@D{M!=`5mil-{! zWCOUZA702e1?ozGx47t*PiNnL)I*!eLBS{d!nH??iaq3+ehw-#1Q%veK6g8Y0vAD_ zzXS;k7Xg$u{%C&gzruO!3SP{Tf6%b5X?AX#CP>o%ap*q+^c4mTLYZbr+8nx`Opk^l z9}a-Ekao%aBwyFF85R6ZOY%{gbh(AGfK4BwL}(r_q*)w))TXN{>H60boJJBnYK#cu@}@vga}j(# zG{4B&JUXLE6;sB=&lB9bmwb==Y!WXA>4M0TZf|Sg>Tb48EF(f3hYKK4gNC*LNUIDQ zS2vK_#`O%>$r_+qiPNvh$3;CfplH}|j~dtNYl?Ts_4rV~Nk7I{*p}A#eiwMZFhL)S zd{>AR+Iv(nJ1#tuRPIeqG*s69nZxudXfzPFus`SJQl>k$@mMe!Mey>EVn_B8LpUF( z;Op-2pCYUvD7b_J?>Q#UE5ykg5SPrjiKJYLr?EoPHcja}dZl#Ri;|#pAffHzDqIa^ zKp4;VISooWYGqq?E+1+Qs&S1K5d8SNj2|_?!U90t{~1j>C*5r>=ge)x>{G-SEfvgZf(84z`7hpl?|R()-v zKZ-p0x@Lyj>H+nZb}UR+cb!0E6RRYU-Nnq z7UZw9@eT9>53O>0_r7zzM;C+ga*0?FE|%H$lEgzIuyZrgdOCWqNW=Z<00m-NLt)SaX*9|>f zaS{zAQs8NYP8^ZuJ65x&S6LP+X?o!~TMiat$j@v7z}>w*G>cksGlIoBS6G!=$G>v3 z=p9{H#Q1CzA8`{XXI;EGENtK|Y*2{xN6VxOObtu3hH;XiDE8 zOL=3}ET5rQECbdAsy-=#4r4(Yw*chJP&RA+ejup2MZEdz=Qcliie_0d-8|JBujgxY}vnAQkY)77dBh0t02hR?+m~Ea-ti)-60dz8|A@CBcfNbf) zvrmW3y;bUPvzy}&rYLG@5fb%j1%EzN%$^b>HqRC=Zs+%h8U_M6JM6;5CaZr7NUX8O zguPW!FC?W}csP}H;xAB6vT+2lNUD-3*_OWbPCBp8q+ZYkWi}$Iwj{D`-k>j1h|vOE zJQ|gjM;NWghsoH+pe{-&NpP0KyS?FDUUzX3Vuj|E>;Pv6rD`$U0eFzaIYS`n;?4cUZ&V=7( zots2qWuHW6wG(%l`wB(nD-wnq&c&i`+@1WpH9zy|c_{%qBE(4_4~_H$n9HnZLh;U38OpiLD02q+ly zGapb#Ax#=Iysb(-i#|`w5}Yy#2|3cG{MN`tcd8rKD6F9q=7*bJP+%K3d=rh%_9S_; zj;YOf2wXW72Bd<+?je;a7O`z=nP_3~uOI$=KaZRp9gzlEt+{A(&6i_@H)#AEQqZaj ztYg@ua<91G_Of)Ic}A~BL$_==jGvHN64p8i)1=f$Hg>sz7PF9?A-Y?A{gYSw6XI*r z4f*Wc?Aa4vDs2lE2ABSd5!n)~Dl1@F(h}mkW5W{^(F)RzVW(~P9%fKt;}Y2(>%0Ef z&$18skNB3mGnVTX(LQkE#j0*)PIpT?LHkRc8sWLI(c_Ye!SSYJfDadXIMy6@#u&f? zHb7p0deQA_f8bY3!D3+3-w5;=?;RVmRiq={i>j5ue=8s00qNh%+kXUNM#&EX4VRyu zH=nTnvf+G$^5ZRZUo`;U%>*1;*D4)>K4fE&jbyo-q_ z2l164{OIQ>eTEY$1JIg-mHoFF@M%jeDG)m8ft-f@kUjs-#k*ft*9(rKgN~5>Z?_Vc z7LPqV2wm?Tb5C9!wb$V&?xPd1SBjzsd z!Lz6R#mlR3SDsXG%A;rK;)*4q2)U~e+zzuEhDhA_Ij2pQrEF&SDKewWWeD=FaVOiJbAcs zFk%(I`PhsZEM4p^l}h7S?Z*FI1SAsZ_i%1xjy=TJ{9rOQY-1jYe~L~BYQ+gdgtDV# zGG~gl+IR0Z^rf{aTc2ny)g=M*A#12-T^y2&o@Tu_NLME#+X98eB30zLPWs*imf-%V} z!>*=nvpXU)cZV?ZKF$fMb(x-TY>&t9aUf!75j@ZS7GvMaQSAYbI z4jZBnonPQ)WRiv9jw-?CKQ`+M33W+gru&9CK|y`!7+M(xN^PtoxKj+Y;dLhRTtVl_ zx*f^gZ2Scmwf*5>=31_)JzEUg3by^Fp#E}I$a77kYiaGlwPy`y#!~)KqNJ#~v^7~# zU4^?4{MK$Pi5V^J@0Xw4x})s1&ZVM&t!eOuGaI51P@;Ji*vj-*6T@r=D;72Q&J-K) zP%15ketvDUJX3O^ONRns!OMlKf~x*Ajj~#A85}*q_M`b@By@({5mIV%8AD#rzkaex zCB>_RdobPg*c)whe{I}^L;F~=^iZx-8(y^BtI<3R{R8WJt@#YYh$10i694 zsrqW8B-$r$lji={>6w?=X;O7Y1X=eEO6Fuc{JKNEMEg zEs+-O%1Zj?64?;Qu_yEgAj zRPq?5*VH{j_ox-jsFU;PAhLSCUvhVK@)Ty>LfyV2#jVzKTj+gT>sgb3pQ8KkgXl8~ zF0ac<>d2QYWc#Z`9eyO|?rB#UNryqWOen@Qta zNFf#DMv7TRa%5zS^yy|KROBy3EN14|+IYwzdmSVg$iQ zI$Q>Si6ce1A{)G3&1=&ocJZoYaJ$m)`Df!`q-Dfxg)zMem9yMzEM|vnUISr|lJX2p zEL3kD?BMw%5die56O2%BN^rLFMK#>5+VB0BOao*ncsOvjk($-@;!Yl^rg_z`poYv4 z=Z_hgyO&g!kDYpDA9cfW7m(Cb3$zp;;mA~99KDopz^HHwIOhh* z4FMEHN<1T~f#ADtiKMP_$~I~&vX!yX%cr`Evg#2}RaG|4i(pE(xU;%Q6)28#E>_7B zA3GEqyIo8Y#5R5!($ zwPwc|Fx8#5J}M4eVaV5maxNn5JX2Ini?v$r`J79XYpQZ2vlN}ViI!ns_56H!#9rN|unhT5GBI z#Nrs>H=X24k4|1XBUc98MPUwR_*XLZ^`tH%!ayZ2+cS1shH4 zBhvj!A8L+auF^R<3m>Nz5UZWWazSXLf^UHcU8wEY5mH+$DM1EkvH)xZ|Gx~bW!%3# zICy=8v%1cuuT>qknLd|Po2`5B`4FD(FYKqykEXx)-8yXlyAGgQr|)$ae}|E4oFm-r zE$Xd7j9w@Pyi$gwbOB+(U=`^APo3vkLOpsw5dZ%2SCcK6aR5B z8*9I5k1NTYiehP~@QKR=n<*2Yi65xrVGk%)4YeDyXw})sTWTBgl{MEiAwq;~;gQ@#idNdy8fj~eL^2Ix zxwN%tSN3L2upm?tleY7u`Z{Bo$g&y98-)2WeuvMv_j?sPs{MRrwtfJ=%v^1__It6~ zAF4GhvA1C{PKLKKbN;8}lMB5YO58>;#}uoRDZ3oBoxyYaP41-|EUV%8YwT7+5d3#i%u1tI;{X_Q}vovC(5j-ss0gWVcBOA6MZ8^wV zc{7QPXh9A7XkK667hRo%KZs@R5#2(##u^|6&;Jp38;In|O7zjXx84LHlwHp|K=nza zU_OH>rlT}RV|%M1mjxxrH9@oJU=fyMKw>*~fME0O=;GcbJya#+m@keiu(oT+*3o6y zdZ6@7zs+~mnc5KVk zrHB^Iszg&Zux3u6rJIY63dG>i97AJ!n+s&H8bkDf0Ee<*@6X+>=Ff)8x&HpHzq}?n zgoa8?8gAjk9E8)5;=JB&YozW;9juvwr5j=r|2M`WP;xC8aO+2F z2b-IIuW44kkAJ?qFR#f(Z3#2jrfcEMwWrF;vd=?qc8$<6qD)Tuc@&<$X5*;JBA=zx zg;_d^7>!Q0gXtQ3!nE~3+Y ztNJ43npA)VoYH|uQzTf%j-dmtC3R35eQmIs8!d)WiX5%6gQdgYnW;6P7rKn0sW}Y~ zPB9(0{tYZsmy@Y56I_pJM#SvuFroHVRnZy>0+oqahcWx=fPnU}RFLnb;{RfXxS^yn6mE{?5QS4Caxmzc-apmT@JbW-BE#(l zh3h(AaVL~oLaX+Yf?Rdijk!x-u>wzHR&|rdYmT9ejnt)xpgQhb6784*4wqSrLzrUv zpym^-H^W{uy+!RJZOSE3@Gu{S=@_$OZEi>e`gF)S6bG@}UOM3)RCdz}X4SEMVU3pc!(q%;NZEf4{mntD=8!fc(Giv;Y?7w z(K~+oa&w1MTQ*n)fhjie~?A7544qT za*-mZ$~=qb>+@dvtx{I5kG4Wpnm%TfU7b?wlXz1bFg=JBg@Nsmf&=6|%O=X{#;Fvi zG{jXXeOQouji(#mvrX2z;dS2L&=I6>M4E=ZF|MYYN`Xx^`VYDhF_2i#cG^w2qfhPZ>+zhzowb{IiKa+dTT|c`XRi9dKoH<| z?fPl45gkp)U`Yyp)6Io{rlwM>!bw_n)?%C%l}VK*SgYG3L3P8dt)ypqxJE2V>QKB| zjBws0`G`RBK1HpEG@>TiF{#&)nMicfE6os*4C~@Y)fjn2i8u;sUm=TJk}RRo1Ua88 zYZF}p65SG)Y6(Q7wZ1XbpcJ?AHKipfp)dDvUgD2G zQ~2`p&o@qg@87RiT~n3$EXJ#AM@~BNk3HLs=@@?-V?JEA5XcT9 z5Ke5FflA?crp8*#*@dJWvLcBaLXY1Q3W=|`F3GIzs*CCIzV*3{O9NHxW2;uOMeFbc}mydQ>%7Eub zJdfvA`*uuS+~gZX%oa5gtgPaRA5ob+p$3I2`ja$GNh2EK+3E0dD z%kH2gFL1aJ&h>tO@%fj-a$awn?JP}V97-`Kyu{}>yH`%4u=?yll5Y1tMRY=bS1$li z!12U%PV;Kx!BuUll+<^m!?;=RpLKJ?*9P{A@F=0VvA0`L1mwqr<*m)jwxEB|&1Xdi z)Fe7In!^*sZM{BGf?4ac7yAj8vwAh+Z9riFXSuy>U|b)fjom?U4#&kST729I0r>Uv zts56#cUSj+Ebe{R)~>Co{QLOcJ~*n>P=6&U>TQCRSKHY9$h)dg?bM{dQUoru6Zhbl zWyi$r7SYaSm4jJwG;D%4l6Yu!T`!6kNlU2XmWKV3*aIt1dN|w%BcJrlrQXbG)j%BV zC~|4{G^D5;^8Z6gXaA*C;U`1N(xNhv3Eu1enqZZRNbC`^WV)@c0O23iNFc1&_h-|_ zNw~Su`liQ@M9Xk!D#WPAr=&g4Y(j=|I?ZSZ1+`8ylB~o;HN3CMRxJm-QblA$e1|0Z zDDj3;fSSvIrj{H&0%-e54(S?59ii)JrHlk$OrIlhI$x5=u+PY?JesR3{B=dtG@)r| z>w?(4Q`g<3J1)Y}IwFKiAV-kTg2p7Wyc1!su8}5aYP;qSH;YjNqRAiwYjH-XnyqCJ zbkyb%-r8TDbq0g*6hnLb6w8-&a=(%D%0>|b6{5YL%*eCb98w91%)+}0Ot=^EcC7;H zm5}JJU&9n~DN&XC%(F0^{?e1@3ia3UEAGskwSJtkY{RkSJ_hWXqz-);OZ$V8&GeF! z@-tMHsN=ipWT2jOm?1CK!~7Hr)I6nld0)R$c>i5@-k&#Bk;hTsySAZAu_QdlQ?wxS zl(u_k;!MM~EFBWTk*$P`$CAsNsT={&>H(8oJ`owbde#Z$^XzM9z8~vvZiwQ6WB~UM zJU}4;4dtJ zUw9+8pzqqIDu)MyXi8FJ_#`yZPTH7lE%^w`LJ7<$TSo#cSQ5f54V13q5tEv!p+zk4 z9cv)rclk~;2bV}RXJ4e*!Lqjl7ij^ONz7p(1am?H-lLCLvqy^@z%l7N;9(>U?y*g= zud(dlsdlm3dOG#t0@h0>A-Pc4WE%qrg_oDyoXCl5R@*xeg(G-Y)Q44E0~WUQn~2R6 z?QHKcVYl*8f>uwZ$C$TEnyd2>J;x3?l{}1$Yj884bM1F(U8Q}rEqu`2JP)bvs$m*8 z;DM%J*$BR3ce;i?M=)xCHZ?_sjiXHUOMeXyeda3?t?GRNK}6_BBMtd<6lzx2_knd= z*0DSxEVhAELZ=x^jh0kmEQ-eOGCs9&Ih$PZ8;J)@{IrqB-6(+cu^YWRdyW9hxq(d# zLk!DM(&BBmVXSd#`*_JKp7Y4kR}&uKhVM`I)QnS`&7RWpV*bG30aV)l@JQ*1egmF;V-i7X6;FrSdJ65jFNjfU9R=Cn}0C?I`ZsRKc?DlFK zo!cw?tM@v_cod_2{-)$quGIUKDr>T}qN;R}?=9~7pPwza(4Qd|HLe~PqIqgQHYI-?CB?BCW zFpKjc!Y&#Md(g*{@rWDxs9tewpPNM{GGdjF8Sp04HlYLU{0}Iztydroro*h1u9nNi zso;@(WZ1U!6wwOCxwh8!{D86_K^J?qtq-Do4x2n>pW1v{0i~1l*RHB4eDtZ?3%;Hd zw_48os)aLXYC#d|37+seUzi}#i>pCX2An2o0I{dJ^G`?Y+#NjqJAUBXMM$Z*GX|R# zx}BLhz@4-OjSyml_&UzH6=RFuPlgan4GOG-wkTM)n7g+4JAiW7h}>3NJSqB-_#7+R z9{S9usleX*i@0zByN#Q98O$&nCCUu5_IBr83n;i?zhfS5zMdw`gb^bOp41;}k=W>v zevpu}XqVX)1k9kZ5kTfcuU}$_Q#Z$plEv|a6u{> z0l5=}o&j#S&TY%sdFGqNC!GVw^Q&zm7NgMC_yL}itVQH^nPVGswk1?z52GS*x=H>RPItYGWbM)aqaoHUO^NltVfLOff0dgNdi!P)EuruQu#5g*nzLWm^efu^}F_ z@i7gi8f@$|OfWGrtkgyb_T+XN=qDeLHrCW+-uF_nq&zt^wKO9`(*B$Zu$kL^Yt?MC z3n<$2dguidTs=AZy@;oc;ENMYEx`M?%SGQtf#+J+>_7Jz-D)w$V*4c%1&DS@Q%(hg zNW_4+opu@}=p2gIs6jJCMyzJYV(m#o2#d0i0+cn0ckrk|QzaMVVRdU|@|Di@FjKCv zffVwACK+H^&JaYns6jiXVK26AfqPLH&o5a>Hrztm{UqWopV=>`{$DzLYo9^MM0L?Y zGR^nzDxhFXKeUq%L95My5wFya2}SA8mkf*hFGZq=Hzs;!dGid>J#6^Eb;H8)n{f>4gGNr3hu8P1ri14R~m$ziz8v9UY*e*Qjve&R3v z0*K$bE%3Yywg7Sec5A$Px^f9dZU}d?D(yPrC7g#4_KG9PKlzZPBODZU5r;#ZLA~D+ z1U9PahPTrB-i;pdJU$Z!GC=e{eTfRrUDl}gNR4S*H8p`&iDVctC^?nKKHi%f*B0fh z{k}EZGYFu$;d6AA!>CxaG|w&CH9X!DCUrIhcq8Q-QoowxNY`YU!u#*$r^TtvqaOFJ zt%Z6htFo#fHxbUMbGKvZGaTsp39WoeWL?K!?oP`w7!~dhh-oYgHLQ-iDG~C^vhNq~ zvVcusyDPJ&Lt>RW>r~4JJPX?p8N15#+Ec+jbhENVDbjbAQVoy08g4I%@4vnLMeZLz zE_#lp2@Vr7$*jd^{2o`QA%3;oim#s%kJiQ?{yN5yZXf(%-pS2c2lc`QqUqZga`LCg z{nCk7n^_u#hNd7f-~~R~ZQ9iUDGHgk*4W<~fm`)BerFXZv;~eu4fyw$j)y$KawBIu zAlVkXyfMnD6@*}iiUr$Ji9KCr;N6Dk`jDRtU16(#gia+znGSD~`~;y+9R(>ojkcvp zwsA`UvDr$>f3E~*s|}JVeDGnro_9@M=Ft%!lXh?>1>oELm{Mo1cU?RrTqq6{>NJ#W zWn2i)F?4ds@gnZ6dsBI(ELY^&Ec6v}n%ww;>;@Oa<2R$2y0}#@D}g)CzpjpC+c^CG zmT||Gcsr2y7IA^oROw;7plAgTzVNo|`AuA{#c4jZ8Z*u!PqkQEScNkPolyL64aPF+ zhvWu=vai^MFBkF=EH2{0#vmS;w#?ptjA8o)qbFv5FB!UV6IUh?Hm_?mP z9oNNK`#hZBz&MO`KkJv6$`BtN4yzrPgCjD`}i_3YH z`x87-fdgVbe3{TkyGqny=lJ72LquZ`35VbY_;)zV!t&8Sa&RuJ;R)E?MC7M|-jsvL zzK2%$0rk}@e(nb@dFIdBx{1L1vJ?Ct_d{w?!&p&fvxw~K^L6)%943X3ao%xabGmzE zS)yzFPVghlG;zE5+%aPke=mi=b-p3ptMiC3Z`Ngg^Nkj3g!AElrd9}mF^+cLlEZWinE`e}SB1bX- zmuaX#wkb>!g@&nND)W_giT+WJ7G&Pd-C7JcXg4G_e7tb6go%PxJ>$`7v~(&WOGOrv zOWOrvge~5wAFfOqd5XBoHAcmO$k)~kS|xhM$%+_uAW_gfGg(o;GHpJ+U~~6yxwO=R zj-ae!QW#YlQxv7I%5&g34Goj+LVlTN#N1NnQ8nTTXN*y5g}B7DqpYAJF@%NFghPP) zFx@8#_@7;u12%Fe1l*G2a45t;t|L}O0s#W`>htUJ0ng{ikN|x76+$Ywtv(uPhz{*Q zkYL?0pgjl?sxb#mn*DP($4Xi+On7t=F)FPrrgtIx^rWB!2@@qI6rUt%vg8sZ`dXB8MW-?#wbtUK zD@sdAr8r%B8fv?WCz9d+05~@zu`eZ-0|wD$&ceVLK%X^RcA2vDlon*LA)Yb?D^;c> zBs9!W!@>=Z$dNOb_eL0*J5OHaMybeWn(3zIFJQMBjvMWVF~&v~EM#0wKC&gT*!Utv zi;izi-r?r{tjhbIt8WD1o=XXKWU)`W5r(_WN`ip8|wQ85K#3ZvwV zI`ejwp_CM7uxP_X#jt2g6lSm-DZp~cKxes1Ni0op`EcCl4T$+h{jDEv^=;;=W5^3F zXXSO`aJpx{j=8Js)90aGWpG-adRnIj&s`4o&zZxn4kjFh7*Q1Gdnm$f_0(I=N*Zvk zuV6}U%@>c3lJjjV3eP)Ff9lVS@&J9!=RZ7DfM<*Xy!TJ;zW;Myo&O>ESGV8o9{rCU zGdCUS1oM<{0lqiwdwbOI`;HNP22y@LK5d9PX4LQKN|C118>6Ai9sZ?Q`dyL#^ z-9rz(G%p_LNed^hGt}d>IPU0ASE%$PExB4?$u7i?%{9Qp>b5 zKEdX;zwr!oO83*WZ{LSLLRqTyuWrfK`sl|w-A|p|VYnI@DkyN%H zhP`lg)q;!*y|1pvAL!P##6hKeoHl&^KV7uw?mIdMp6j7K;V!A1x>8*$)t@G4g6d3l zC~NsCmCY9T3%B1&juWnU_b`7aptt>Y9OPYJL%@BM5`4Aqn=fJIi3>KrwU58d*;kOtIep|Zg5RS0Dqq5u|BO^4fAzdMCH*-7008@poErcD literal 0 HcmV?d00001 diff --git a/apps/tx-builder/src/components/FixedIcon/images/arrowReceived.tsx b/apps/tx-builder/src/components/FixedIcon/images/arrowReceived.tsx new file mode 100644 index 000000000..db52c68b9 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/arrowReceived.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/arrowReceivedWhite.tsx b/apps/tx-builder/src/components/FixedIcon/images/arrowReceivedWhite.tsx new file mode 100644 index 000000000..c827097bc --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/arrowReceivedWhite.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/arrowSent.tsx b/apps/tx-builder/src/components/FixedIcon/images/arrowSent.tsx new file mode 100644 index 000000000..53fb1e697 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/arrowSent.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/arrowSentWhite.tsx b/apps/tx-builder/src/components/FixedIcon/images/arrowSentWhite.tsx new file mode 100644 index 000000000..89c2e70c4 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/arrowSentWhite.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/arrowSort.tsx b/apps/tx-builder/src/components/FixedIcon/images/arrowSort.tsx new file mode 100644 index 000000000..7ff362f9a --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/arrowSort.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/bullit.tsx b/apps/tx-builder/src/components/FixedIcon/images/bullit.tsx new file mode 100644 index 000000000..787496322 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/bullit.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/chevronDown.tsx b/apps/tx-builder/src/components/FixedIcon/images/chevronDown.tsx new file mode 100644 index 000000000..ce111fd02 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/chevronDown.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/chevronLeft.tsx b/apps/tx-builder/src/components/FixedIcon/images/chevronLeft.tsx new file mode 100644 index 000000000..5d34bd879 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/chevronLeft.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/chevronRight.tsx b/apps/tx-builder/src/components/FixedIcon/images/chevronRight.tsx new file mode 100644 index 000000000..46dcd7a21 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/chevronRight.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/chevronUp.tsx b/apps/tx-builder/src/components/FixedIcon/images/chevronUp.tsx new file mode 100644 index 000000000..7b30e056b --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/chevronUp.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/connectedRinkeby.tsx b/apps/tx-builder/src/components/FixedIcon/images/connectedRinkeby.tsx new file mode 100644 index 000000000..fbc514c9e --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/connectedRinkeby.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/connectedWallet.tsx b/apps/tx-builder/src/components/FixedIcon/images/connectedWallet.tsx new file mode 100644 index 000000000..6372e94e7 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/connectedWallet.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/creatingInProgress.tsx b/apps/tx-builder/src/components/FixedIcon/images/creatingInProgress.tsx new file mode 100644 index 000000000..90937ac89 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/creatingInProgress.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +const icon = ( + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/dropdownArrowSmall.tsx b/apps/tx-builder/src/components/FixedIcon/images/dropdownArrowSmall.tsx new file mode 100644 index 000000000..531776bb5 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/dropdownArrowSmall.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/networkError.tsx b/apps/tx-builder/src/components/FixedIcon/images/networkError.tsx new file mode 100644 index 000000000..daff9c9e3 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/networkError.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +const icon = ( + + + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/notConnected.tsx b/apps/tx-builder/src/components/FixedIcon/images/notConnected.tsx new file mode 100644 index 000000000..1b2b19246 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/notConnected.tsx @@ -0,0 +1,18 @@ +import React from 'react' + +const icon = ( + + + + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/notOwner.tsx b/apps/tx-builder/src/components/FixedIcon/images/notOwner.tsx new file mode 100644 index 000000000..e2ea0945d --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/notOwner.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +const icon = ( + + + + + + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/options.tsx b/apps/tx-builder/src/components/FixedIcon/images/options.tsx new file mode 100644 index 000000000..6ab2a5ab0 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/options.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/plus.tsx b/apps/tx-builder/src/components/FixedIcon/images/plus.tsx new file mode 100644 index 000000000..408a2bf71 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/plus.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/settingsChange.tsx b/apps/tx-builder/src/components/FixedIcon/images/settingsChange.tsx new file mode 100644 index 000000000..9ada76f01 --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/settingsChange.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/images/threeDots.tsx b/apps/tx-builder/src/components/FixedIcon/images/threeDots.tsx new file mode 100644 index 000000000..43dfe865d --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/images/threeDots.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const icon = ( + + + + + + + +) + +export default icon diff --git a/apps/tx-builder/src/components/FixedIcon/index.tsx b/apps/tx-builder/src/components/FixedIcon/index.tsx new file mode 100644 index 000000000..823e5a03e --- /dev/null +++ b/apps/tx-builder/src/components/FixedIcon/index.tsx @@ -0,0 +1,63 @@ +import React from 'react' + +import arrowSort from './images/arrowSort' +import connectedRinkeby from './images/connectedRinkeby' +import connectedWallet from './images/connectedWallet' +import bullit from './images/bullit' +import dropdownArrowSmall from './images/dropdownArrowSmall' +import arrowReceived from './images/arrowReceived' +import arrowReceivedWhite from './images/arrowReceivedWhite' +import arrowSent from './images/arrowSent' +import arrowSentWhite from './images/arrowSentWhite' +import threeDots from './images/threeDots' +import options from './images/options' +import plus from './images/plus' +import chevronRight from './images/chevronRight' +import chevronLeft from './images/chevronLeft' +import chevronUp from './images/chevronUp' +import chevronDown from './images/chevronDown' +import settingsChange from './images/settingsChange' +import creatingInProgress from './images/creatingInProgress' +import notOwner from './images/notOwner' +import notConnected from './images/notConnected' +import networkError from './images/networkError' + +const icons = { + arrowSort, + connectedRinkeby, + connectedWallet, + bullit, + dropdownArrowSmall, + arrowReceived, + arrowReceivedWhite, + arrowSent, + arrowSentWhite, + threeDots, + options, + plus, + chevronRight, + chevronLeft, + chevronUp, + chevronDown, + settingsChange, + creatingInProgress, + notOwner, + notConnected, + networkError, +} + +export type IconType = typeof icons +export type IconTypes = keyof IconType + +type Props = { + type: IconTypes +} + +/** + * The `FixedIcon` renders an icon + */ +function FixedIcon({ type }: Props): React.ReactElement { + return {icons[type]} +} + +export default FixedIcon diff --git a/apps/tx-builder/src/components/Icon/images/add.tsx b/apps/tx-builder/src/components/Icon/images/add.tsx new file mode 100644 index 000000000..7bfabcb56 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/add.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/addressBook.tsx b/apps/tx-builder/src/components/Icon/images/addressBook.tsx new file mode 100644 index 000000000..f31e05503 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/addressBook.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx b/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx new file mode 100644 index 000000000..c5e81f589 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/alert.tsx b/apps/tx-builder/src/components/Icon/images/alert.tsx new file mode 100644 index 000000000..7bbb9897a --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/alert.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/allowances.tsx b/apps/tx-builder/src/components/Icon/images/allowances.tsx new file mode 100644 index 000000000..4761e4d49 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/allowances.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/apps.tsx b/apps/tx-builder/src/components/Icon/images/apps.tsx new file mode 100644 index 000000000..0d3e77a7f --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/apps.tsx @@ -0,0 +1,40 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + + ), + md: ( + + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/arrowDown.tsx b/apps/tx-builder/src/components/Icon/images/arrowDown.tsx new file mode 100644 index 000000000..6e62ad647 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/arrowDown.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx b/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx new file mode 100644 index 000000000..4c1538e6b --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/arrowRight.tsx b/apps/tx-builder/src/components/Icon/images/arrowRight.tsx new file mode 100644 index 000000000..1c366234c --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/arrowRight.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/arrowUp.tsx b/apps/tx-builder/src/components/Icon/images/arrowUp.tsx new file mode 100644 index 000000000..04c60b947 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/arrowUp.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/assets.tsx b/apps/tx-builder/src/components/Icon/images/assets.tsx new file mode 100644 index 000000000..76fd8f274 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/assets.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx b/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx new file mode 100644 index 000000000..abf2e8fed --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/bookmark.tsx b/apps/tx-builder/src/components/Icon/images/bookmark.tsx new file mode 100644 index 000000000..528ccf212 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/bookmark.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + ), + md: ( + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx b/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx new file mode 100644 index 000000000..a8fdec094 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + ), + md: ( + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/camera.tsx b/apps/tx-builder/src/components/Icon/images/camera.tsx new file mode 100644 index 000000000..e7caa52be --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/camera.tsx @@ -0,0 +1,37 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/chain.tsx b/apps/tx-builder/src/components/Icon/images/chain.tsx new file mode 100644 index 000000000..32acfada4 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/chain.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/check.tsx b/apps/tx-builder/src/components/Icon/images/check.tsx new file mode 100644 index 000000000..4487379d6 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/check.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/circleCheck.tsx b/apps/tx-builder/src/components/Icon/images/circleCheck.tsx new file mode 100644 index 000000000..7746709e7 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/circleCheck.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/circleCross.tsx b/apps/tx-builder/src/components/Icon/images/circleCross.tsx new file mode 100644 index 000000000..a3774fde3 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/circleCross.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx b/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx new file mode 100644 index 000000000..c358edc31 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/code.tsx b/apps/tx-builder/src/components/Icon/images/code.tsx new file mode 100644 index 000000000..dda613230 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/code.tsx @@ -0,0 +1,27 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/collectibles.tsx b/apps/tx-builder/src/components/Icon/images/collectibles.tsx new file mode 100644 index 000000000..e87b01107 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/collectibles.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + + + + ), + md: ( + + + + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/copy.tsx b/apps/tx-builder/src/components/Icon/images/copy.tsx new file mode 100644 index 000000000..d3a07d584 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/copy.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/cross.tsx b/apps/tx-builder/src/components/Icon/images/cross.tsx new file mode 100644 index 000000000..30b62cb84 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/cross.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/currency.tsx b/apps/tx-builder/src/components/Icon/images/currency.tsx new file mode 100644 index 000000000..306f8fe9b --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/currency.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/delete.tsx b/apps/tx-builder/src/components/Icon/images/delete.tsx new file mode 100644 index 000000000..91e472c3f --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/delete.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/devicePassword.tsx b/apps/tx-builder/src/components/Icon/images/devicePassword.tsx new file mode 100644 index 000000000..647658eea --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/devicePassword.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/edit.tsx b/apps/tx-builder/src/components/Icon/images/edit.tsx new file mode 100644 index 000000000..e1286ad05 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/edit.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/error.tsx b/apps/tx-builder/src/components/Icon/images/error.tsx new file mode 100644 index 000000000..1fb30bab8 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/error.tsx @@ -0,0 +1,40 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + ), + md: ( + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/eth.tsx b/apps/tx-builder/src/components/Icon/images/eth.tsx new file mode 100644 index 000000000..ff3a72cbd --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/eth.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/export.tsx b/apps/tx-builder/src/components/Icon/images/export.tsx new file mode 100644 index 000000000..28da74fe6 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/export.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + ), + md: ( + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/externalLink.tsx b/apps/tx-builder/src/components/Icon/images/externalLink.tsx new file mode 100644 index 000000000..11e22ebdb --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/externalLink.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/eye.tsx b/apps/tx-builder/src/components/Icon/images/eye.tsx new file mode 100644 index 000000000..de6a38ac9 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/eye.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/eyeOff.tsx b/apps/tx-builder/src/components/Icon/images/eyeOff.tsx new file mode 100644 index 000000000..c99eaae25 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/eyeOff.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/filledCross.tsx b/apps/tx-builder/src/components/Icon/images/filledCross.tsx new file mode 100644 index 000000000..d5e30db54 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/filledCross.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx b/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx new file mode 100644 index 000000000..ba4ef1f65 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx @@ -0,0 +1,46 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + ), + md: ( + + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx b/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx new file mode 100644 index 000000000..7232682d2 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx @@ -0,0 +1,42 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/getInTouch.tsx b/apps/tx-builder/src/components/Icon/images/getInTouch.tsx new file mode 100644 index 000000000..8cfa45fc3 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/getInTouch.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/gift.tsx b/apps/tx-builder/src/components/Icon/images/gift.tsx new file mode 100644 index 000000000..fa29b7c3f --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/gift.tsx @@ -0,0 +1,72 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/home.tsx b/apps/tx-builder/src/components/Icon/images/home.tsx new file mode 100644 index 000000000..99f1c6ae8 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/home.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/import.tsx b/apps/tx-builder/src/components/Icon/images/import.tsx new file mode 100644 index 000000000..c7dd3c43b --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/import.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + ), + md: ( + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/info.tsx b/apps/tx-builder/src/components/Icon/images/info.tsx new file mode 100644 index 000000000..0f546863f --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/info.tsx @@ -0,0 +1,40 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + ), + md: ( + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/knowledge.tsx b/apps/tx-builder/src/components/Icon/images/knowledge.tsx new file mode 100644 index 000000000..bcf22aa97 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/knowledge.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/licenses.tsx b/apps/tx-builder/src/components/Icon/images/licenses.tsx new file mode 100644 index 000000000..ced0f3f21 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/licenses.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/loadSafe.tsx b/apps/tx-builder/src/components/Icon/images/loadSafe.tsx new file mode 100644 index 000000000..32de0a881 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/loadSafe.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/locked.tsx b/apps/tx-builder/src/components/Icon/images/locked.tsx new file mode 100644 index 000000000..a653e04cf --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/locked.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx b/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx new file mode 100644 index 000000000..499bd6e25 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/noInternet.tsx b/apps/tx-builder/src/components/Icon/images/noInternet.tsx new file mode 100644 index 000000000..790145e5a --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/noInternet.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/owners.tsx b/apps/tx-builder/src/components/Icon/images/owners.tsx new file mode 100644 index 000000000..318c96344 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/owners.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/paste.tsx b/apps/tx-builder/src/components/Icon/images/paste.tsx new file mode 100644 index 000000000..5adbf45fd --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/paste.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/paymentToken.tsx b/apps/tx-builder/src/components/Icon/images/paymentToken.tsx new file mode 100644 index 000000000..13d59aa83 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/paymentToken.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx b/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx new file mode 100644 index 000000000..4665d6be2 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/qrCode.tsx b/apps/tx-builder/src/components/Icon/images/qrCode.tsx new file mode 100644 index 000000000..42617ab42 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/qrCode.tsx @@ -0,0 +1,78 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/question.tsx b/apps/tx-builder/src/components/Icon/images/question.tsx new file mode 100644 index 000000000..54f118c8c --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/question.tsx @@ -0,0 +1,39 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/rateApp.tsx b/apps/tx-builder/src/components/Icon/images/rateApp.tsx new file mode 100644 index 000000000..da0641758 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/rateApp.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/received.tsx b/apps/tx-builder/src/components/Icon/images/received.tsx new file mode 100644 index 000000000..e7e95260d --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/received.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/recover.tsx b/apps/tx-builder/src/components/Icon/images/recover.tsx new file mode 100644 index 000000000..488890655 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/recover.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx b/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx new file mode 100644 index 000000000..4c2b440a2 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx b/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx new file mode 100644 index 000000000..0ed5525a9 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/restricted.tsx b/apps/tx-builder/src/components/Icon/images/restricted.tsx new file mode 100644 index 000000000..21591162c --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/restricted.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/resync.tsx b/apps/tx-builder/src/components/Icon/images/resync.tsx new file mode 100644 index 000000000..5164b6b6a --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/resync.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/rocket.tsx b/apps/tx-builder/src/components/Icon/images/rocket.tsx new file mode 100644 index 000000000..b4f6bbbaa --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/rocket.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/safe.tsx b/apps/tx-builder/src/components/Icon/images/safe.tsx new file mode 100644 index 000000000..e01a52a16 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/safe.tsx @@ -0,0 +1,39 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/scan.tsx b/apps/tx-builder/src/components/Icon/images/scan.tsx new file mode 100644 index 000000000..612b95aff --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/scan.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/search.tsx b/apps/tx-builder/src/components/Icon/images/search.tsx new file mode 100644 index 000000000..1034e83f5 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/search.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/sendAgain.tsx b/apps/tx-builder/src/components/Icon/images/sendAgain.tsx new file mode 100644 index 000000000..c935cb835 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/sendAgain.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/sent.tsx b/apps/tx-builder/src/components/Icon/images/sent.tsx new file mode 100644 index 000000000..4279522c8 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/sent.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/serverError.tsx b/apps/tx-builder/src/components/Icon/images/serverError.tsx new file mode 100644 index 000000000..6bbd6f5ba --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/serverError.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/settings.tsx b/apps/tx-builder/src/components/Icon/images/settings.tsx new file mode 100644 index 000000000..8b4829127 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/settings.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/settingsChange.tsx b/apps/tx-builder/src/components/Icon/images/settingsChange.tsx new file mode 100644 index 000000000..c018296b3 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/settingsChange.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/settingsTool.tsx b/apps/tx-builder/src/components/Icon/images/settingsTool.tsx new file mode 100644 index 000000000..9cee1412e --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/settingsTool.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/share.tsx b/apps/tx-builder/src/components/Icon/images/share.tsx new file mode 100644 index 000000000..cd21a60cb --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/share.tsx @@ -0,0 +1,27 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx b/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx new file mode 100644 index 000000000..9cb6ef82e --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx b/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx new file mode 100644 index 000000000..ac428ef2a --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/unlocked.tsx b/apps/tx-builder/src/components/Icon/images/unlocked.tsx new file mode 100644 index 000000000..1e8c56fda --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/unlocked.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + + ), + md: ( + + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/userEdit.tsx b/apps/tx-builder/src/components/Icon/images/userEdit.tsx new file mode 100644 index 000000000..8f649e7d7 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/userEdit.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/images/wallet.tsx b/apps/tx-builder/src/components/Icon/images/wallet.tsx new file mode 100644 index 000000000..f40ed2544 --- /dev/null +++ b/apps/tx-builder/src/components/Icon/images/wallet.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + sm: ( + + + + + + + ), + md: ( + + + + + + + ), +} diff --git a/apps/tx-builder/src/components/Icon/index.tsx b/apps/tx-builder/src/components/Icon/index.tsx new file mode 100644 index 000000000..86187756b --- /dev/null +++ b/apps/tx-builder/src/components/Icon/index.tsx @@ -0,0 +1,204 @@ +import React from 'react' +import styled from 'styled-components' + +import add from './images/add' +import addressBook from './images/addressBook' +import addressBookAdd from './images/addressBookAdd' +import alert from './images/alert' +import allowances from './images/allowances' +import apps from './images/apps' +import arrowUp from './images/arrowUp' +import arrowRight from './images/arrowRight' +import arrowDown from './images/arrowDown' +import arrowLeft from './images/arrowLeft' +import assets from './images/assets' +import awaitingConfirmations from './images/awaitingConfirmations' +import bookmark from './images/bookmark' +import bookmarkFilled from './images/bookmarkFilled' +import camera from './images/camera' +import chain from './images/chain' +import check from './images/check' +import circleCheck from './images/circleCheck' +import circleCross from './images/circleCross' +import circleDropdown from './images/circleDropdown' +import code from './images/code' +import collectibles from './images/collectibles' +import copy from './images/copy' +import cross from './images/cross' +import currency from './images/currency' +import deleteIcon from './images/delete' +import devicePassword from './images/devicePassword' +import edit from './images/edit' +import error from './images/error' +import eth from './images/eth' +import exportImg from './images/export' +import externalLink from './images/externalLink' +import eye from './images/eye' +import eyeOff from './images/eyeOff' +import filledCross from './images/filledCross' +import fingerPrint from './images/fingerPrint' +import fuelIndicator from './images/fuelIndicator' +import getInTouch from './images/getInTouch' +import gift from './images/gift' +import home from './images/home' +import importImg from './images/import' +import info from './images/info' +import knowledge from './images/knowledge' +import licenses from './images/licenses' +import loadSafe from './images/loadSafe' +import locked from './images/locked' +import mobileConfirm from './images/mobileConfirm' +import noInternet from './images/noInternet' +import owners from './images/owners' +import paste from './images/paste' +import paymentToken from './images/paymentToken' +import privacyPolicy from './images/privacyPolicy' +import qrCode from './images/qrCode' +import question from './images/question' +import rateApp from './images/rateApp' +import received from './images/received' +import recover from './images/recover' +import replaceOwner from './images/replaceOwner' +import requiredConfirmations from './images/requiredConfirmations' +import restricted from './images/restricted' +import resync from './images/resync' +import rocket from './images/rocket' +import safe from './images/safe' +import scan from './images/scan' +import search from './images/search' +import sendAgain from './images/sendAgain' +import sent from './images/sent' +import serverError from './images/serverError' +import settings from './images/settings' +import settingsChange from './images/settingsChange' +import settingsTool from './images/settingsTool' +import share from './images/share' +import termsOfUse from './images/termsOfUse' +import transactionsInactive from './images/transactionsInactive' +import unlocked from './images/unlocked' +import userEdit from './images/userEdit' +import wallet from './images/wallet' +import { type Theme } from '@material-ui/core/styles' +import { Tooltip } from '../Tooltip' + +const StyledIcon = styled.span<{ color?: keyof Theme['palette'] }>` + display: inline-flex; + + .icon-color { + fill: ${({ theme, color }) => (color ? theme.palette[color].main : '#B2B5B2')}; + } + + .icon-stroke { + stroke: ${({ theme, color }) => (color ? theme.palette[color].main : '#B2B5B2')}; + } +` + +const icons = { + add, + addressBook, + addressBookAdd, + alert, + allowances, + apps, + arrowUp, + arrowLeft, + arrowDown, + arrowRight, + assets, + awaitingConfirmations, + bookmark, + bookmarkFilled, + camera, + chain, + check, + circleCheck, + circleCross, + circleDropdown, + code, + collectibles, + copy, + cross, + currency, + delete: deleteIcon, + devicePassword, + edit, + error, + eth, + exportImg, + externalLink, + eye, + eyeOff, + filledCross, + fingerPrint, + fuelIndicator, + getInTouch, + gift, + home, + importImg, + info, + knowledge, + licenses, + loadSafe, + locked, + mobileConfirm, + noInternet, + owners, + paste, + paymentToken, + privacyPolicy, + qrCode, + question, + rateApp, + received, + recover, + replaceOwner, + requiredConfirmations, + restricted, + resync, + rocket, + safe, + scan, + search, + sendAgain, + sent, + serverError, + settings, + settingsChange, + settingsTool, + share, + termsOfUse, + transactionsInactive, + unlocked, + userEdit, + wallet, +} + +export type IconType = typeof icons +export type IconTypes = keyof IconType + +export type IconProps = { + type: IconTypes + size: 'sm' | 'md' + color?: keyof Theme['palette'] + tooltip?: string + className?: string +} + +/** + * The `Icon` renders an icon, it can be one already defined specified by + * the type Iconprops or custom one using the customUrl. + */ +export const Icon = ({ type, size, color, tooltip, className }: IconProps): React.ReactElement => { + const IconElement = ( + + {icons[type][size]} + + ) + return tooltip === undefined ? ( + IconElement + ) : ( + + {IconElement} + + ) +} diff --git a/apps/tx-builder/src/components/IconText/index.tsx b/apps/tx-builder/src/components/IconText/index.tsx new file mode 100644 index 000000000..f2ec58512 --- /dev/null +++ b/apps/tx-builder/src/components/IconText/index.tsx @@ -0,0 +1,73 @@ +import React from 'react' +import styled from 'styled-components' +import { type Theme } from '@material-ui/core/styles' + +import { Icon, IconProps, IconType } from '../Icon' +import Text from '../Text' + +const iconTextMargins = { + xxs: '4px', + xs: '6px', + sm: '8px', + md: '12px', + lg: '16px', + xl: '20px', + xxl: '24px', +} + +type IconMargins = keyof typeof iconTextMargins + +type Props = { + iconType: keyof IconType + iconSize: IconProps['size'] + iconColor?: keyof Theme['palette'] + margin?: IconMargins + color?: keyof Theme['palette'] + text: string + className?: string + iconSide?: 'left' | 'right' +} + +const LeftIconText = styled.div<{ margin: IconMargins }>` + display: flex; + align-items: center; + svg { + margin: 0 ${({ margin }) => iconTextMargins[margin]} 0 0; + } +` + +const RightIconText = styled.div<{ margin: IconMargins }>` + display: flex; + align-items: center; + svg { + margin: 0 0 0 ${({ margin }) => iconTextMargins[margin]}; + } +` + +/** + * The `IconText` renders an icon next to a text + */ +const IconText = ({ + iconSize, + margin = 'xs', + iconType, + iconColor, + text, + iconSide = 'left', + color, + className, +}: Props): React.ReactElement => { + return iconSide === 'right' ? ( + + {text} + + + ) : ( + + + {text} + + ) +} + +export default IconText From fc937bae6eca7977d1f1b3e29414328e6620b012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Fri, 4 Oct 2024 11:19:11 +0200 Subject: [PATCH 2/5] fix(tx-builder): remove unused icons and components --- .../src/components/Icon/images/add.tsx | 36 --------- .../components/Icon/images/addressBook.tsx | 28 ------- .../components/Icon/images/addressBookAdd.tsx | 26 ------- .../src/components/Icon/images/allowances.tsx | 26 ------- .../src/components/Icon/images/apps.tsx | 40 ---------- .../src/components/Icon/images/arrowDown.tsx | 26 ------- .../src/components/Icon/images/arrowLeft.tsx | 38 --------- .../src/components/Icon/images/arrowRight.tsx | 38 --------- .../src/components/Icon/images/arrowUp.tsx | 38 --------- .../src/components/Icon/images/assets.tsx | 36 --------- .../Icon/images/awaitingConfirmations.tsx | 34 -------- .../src/components/Icon/images/camera.tsx | 37 --------- .../src/components/Icon/images/chain.tsx | 38 --------- .../components/Icon/images/circleCheck.tsx | 38 --------- .../components/Icon/images/circleCross.tsx | 36 --------- .../components/Icon/images/circleDropdown.tsx | 36 --------- .../components/Icon/images/collectibles.tsx | 38 --------- .../src/components/Icon/images/currency.tsx | 30 ------- .../components/Icon/images/devicePassword.tsx | 38 --------- .../src/components/Icon/images/error.tsx | 40 ---------- .../src/components/Icon/images/eth.tsx | 26 ------- .../src/components/Icon/images/export.tsx | 36 --------- .../src/components/Icon/images/eye.tsx | 34 -------- .../src/components/Icon/images/eyeOff.tsx | 30 ------- .../components/Icon/images/filledCross.tsx | 26 ------- .../components/Icon/images/fingerPrint.tsx | 46 ----------- .../components/Icon/images/fuelIndicator.tsx | 42 ---------- .../src/components/Icon/images/getInTouch.tsx | 26 ------- .../src/components/Icon/images/gift.tsx | 72 ----------------- .../src/components/Icon/images/home.tsx | 28 ------- .../src/components/Icon/images/knowledge.tsx | 26 ------- .../src/components/Icon/images/licenses.tsx | 34 -------- .../src/components/Icon/images/loadSafe.tsx | 26 ------- .../src/components/Icon/images/locked.tsx | 34 -------- .../components/Icon/images/mobileConfirm.tsx | 34 -------- .../src/components/Icon/images/noInternet.tsx | 34 -------- .../src/components/Icon/images/owners.tsx | 26 ------- .../src/components/Icon/images/paste.tsx | 28 ------- .../components/Icon/images/paymentToken.tsx | 28 ------- .../components/Icon/images/privacyPolicy.tsx | 28 ------- .../src/components/Icon/images/qrCode.tsx | 78 ------------------- .../src/components/Icon/images/question.tsx | 39 ---------- .../src/components/Icon/images/rateApp.tsx | 26 ------- .../src/components/Icon/images/received.tsx | 36 --------- .../src/components/Icon/images/recover.tsx | 38 --------- .../components/Icon/images/replaceOwner.tsx | 26 ------- .../Icon/images/requiredConfirmations.tsx | 30 ------- .../src/components/Icon/images/restricted.tsx | 26 ------- .../src/components/Icon/images/resync.tsx | 26 ------- .../src/components/Icon/images/rocket.tsx | 28 ------- .../src/components/Icon/images/safe.tsx | 39 ---------- .../src/components/Icon/images/scan.tsx | 30 ------- .../src/components/Icon/images/search.tsx | 26 ------- .../src/components/Icon/images/sendAgain.tsx | 38 --------- .../src/components/Icon/images/sent.tsx | 36 --------- .../components/Icon/images/serverError.tsx | 34 -------- .../src/components/Icon/images/settings.tsx | 26 ------- .../components/Icon/images/settingsChange.tsx | 36 --------- .../components/Icon/images/settingsTool.tsx | 28 ------- .../src/components/Icon/images/share.tsx | 27 ------- .../Icon/images/transactionsInactive.tsx | 26 ------- .../src/components/Icon/images/unlocked.tsx | 34 -------- .../src/components/Icon/images/userEdit.tsx | 26 ------- .../src/components/Icon/images/wallet.tsx | 28 ------- 64 files changed, 2148 deletions(-) delete mode 100644 apps/tx-builder/src/components/Icon/images/add.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/addressBook.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/allowances.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/apps.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/arrowDown.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/arrowLeft.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/arrowRight.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/arrowUp.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/assets.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/camera.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/chain.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/circleCheck.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/circleCross.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/circleDropdown.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/collectibles.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/currency.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/devicePassword.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/error.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/eth.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/export.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/eye.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/eyeOff.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/filledCross.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/fingerPrint.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/getInTouch.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/gift.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/home.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/knowledge.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/licenses.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/loadSafe.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/locked.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/noInternet.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/owners.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/paste.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/paymentToken.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/qrCode.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/question.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/rateApp.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/received.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/recover.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/replaceOwner.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/restricted.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/resync.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/rocket.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/safe.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/scan.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/search.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/sendAgain.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/sent.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/serverError.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/settings.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/settingsChange.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/settingsTool.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/share.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/unlocked.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/userEdit.tsx delete mode 100644 apps/tx-builder/src/components/Icon/images/wallet.tsx diff --git a/apps/tx-builder/src/components/Icon/images/add.tsx b/apps/tx-builder/src/components/Icon/images/add.tsx deleted file mode 100644 index 7bfabcb56..000000000 --- a/apps/tx-builder/src/components/Icon/images/add.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/addressBook.tsx b/apps/tx-builder/src/components/Icon/images/addressBook.tsx deleted file mode 100644 index f31e05503..000000000 --- a/apps/tx-builder/src/components/Icon/images/addressBook.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx b/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx deleted file mode 100644 index c5e81f589..000000000 --- a/apps/tx-builder/src/components/Icon/images/addressBookAdd.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/allowances.tsx b/apps/tx-builder/src/components/Icon/images/allowances.tsx deleted file mode 100644 index 4761e4d49..000000000 --- a/apps/tx-builder/src/components/Icon/images/allowances.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/apps.tsx b/apps/tx-builder/src/components/Icon/images/apps.tsx deleted file mode 100644 index 0d3e77a7f..000000000 --- a/apps/tx-builder/src/components/Icon/images/apps.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - - ), - md: ( - - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/arrowDown.tsx b/apps/tx-builder/src/components/Icon/images/arrowDown.tsx deleted file mode 100644 index 6e62ad647..000000000 --- a/apps/tx-builder/src/components/Icon/images/arrowDown.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx b/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx deleted file mode 100644 index 4c1538e6b..000000000 --- a/apps/tx-builder/src/components/Icon/images/arrowLeft.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/arrowRight.tsx b/apps/tx-builder/src/components/Icon/images/arrowRight.tsx deleted file mode 100644 index 1c366234c..000000000 --- a/apps/tx-builder/src/components/Icon/images/arrowRight.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/arrowUp.tsx b/apps/tx-builder/src/components/Icon/images/arrowUp.tsx deleted file mode 100644 index 04c60b947..000000000 --- a/apps/tx-builder/src/components/Icon/images/arrowUp.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/assets.tsx b/apps/tx-builder/src/components/Icon/images/assets.tsx deleted file mode 100644 index 76fd8f274..000000000 --- a/apps/tx-builder/src/components/Icon/images/assets.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx b/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx deleted file mode 100644 index abf2e8fed..000000000 --- a/apps/tx-builder/src/components/Icon/images/awaitingConfirmations.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/camera.tsx b/apps/tx-builder/src/components/Icon/images/camera.tsx deleted file mode 100644 index e7caa52be..000000000 --- a/apps/tx-builder/src/components/Icon/images/camera.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/chain.tsx b/apps/tx-builder/src/components/Icon/images/chain.tsx deleted file mode 100644 index 32acfada4..000000000 --- a/apps/tx-builder/src/components/Icon/images/chain.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/circleCheck.tsx b/apps/tx-builder/src/components/Icon/images/circleCheck.tsx deleted file mode 100644 index 7746709e7..000000000 --- a/apps/tx-builder/src/components/Icon/images/circleCheck.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/circleCross.tsx b/apps/tx-builder/src/components/Icon/images/circleCross.tsx deleted file mode 100644 index a3774fde3..000000000 --- a/apps/tx-builder/src/components/Icon/images/circleCross.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx b/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx deleted file mode 100644 index c358edc31..000000000 --- a/apps/tx-builder/src/components/Icon/images/circleDropdown.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/collectibles.tsx b/apps/tx-builder/src/components/Icon/images/collectibles.tsx deleted file mode 100644 index e87b01107..000000000 --- a/apps/tx-builder/src/components/Icon/images/collectibles.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - - - - ), - md: ( - - - - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/currency.tsx b/apps/tx-builder/src/components/Icon/images/currency.tsx deleted file mode 100644 index 306f8fe9b..000000000 --- a/apps/tx-builder/src/components/Icon/images/currency.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/devicePassword.tsx b/apps/tx-builder/src/components/Icon/images/devicePassword.tsx deleted file mode 100644 index 647658eea..000000000 --- a/apps/tx-builder/src/components/Icon/images/devicePassword.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/error.tsx b/apps/tx-builder/src/components/Icon/images/error.tsx deleted file mode 100644 index 1fb30bab8..000000000 --- a/apps/tx-builder/src/components/Icon/images/error.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - ), - md: ( - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/eth.tsx b/apps/tx-builder/src/components/Icon/images/eth.tsx deleted file mode 100644 index ff3a72cbd..000000000 --- a/apps/tx-builder/src/components/Icon/images/eth.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/export.tsx b/apps/tx-builder/src/components/Icon/images/export.tsx deleted file mode 100644 index 28da74fe6..000000000 --- a/apps/tx-builder/src/components/Icon/images/export.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - ), - md: ( - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/eye.tsx b/apps/tx-builder/src/components/Icon/images/eye.tsx deleted file mode 100644 index de6a38ac9..000000000 --- a/apps/tx-builder/src/components/Icon/images/eye.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/eyeOff.tsx b/apps/tx-builder/src/components/Icon/images/eyeOff.tsx deleted file mode 100644 index c99eaae25..000000000 --- a/apps/tx-builder/src/components/Icon/images/eyeOff.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/filledCross.tsx b/apps/tx-builder/src/components/Icon/images/filledCross.tsx deleted file mode 100644 index d5e30db54..000000000 --- a/apps/tx-builder/src/components/Icon/images/filledCross.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx b/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx deleted file mode 100644 index ba4ef1f65..000000000 --- a/apps/tx-builder/src/components/Icon/images/fingerPrint.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - ), - md: ( - - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx b/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx deleted file mode 100644 index 7232682d2..000000000 --- a/apps/tx-builder/src/components/Icon/images/fuelIndicator.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/getInTouch.tsx b/apps/tx-builder/src/components/Icon/images/getInTouch.tsx deleted file mode 100644 index 8cfa45fc3..000000000 --- a/apps/tx-builder/src/components/Icon/images/getInTouch.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/gift.tsx b/apps/tx-builder/src/components/Icon/images/gift.tsx deleted file mode 100644 index fa29b7c3f..000000000 --- a/apps/tx-builder/src/components/Icon/images/gift.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/home.tsx b/apps/tx-builder/src/components/Icon/images/home.tsx deleted file mode 100644 index 99f1c6ae8..000000000 --- a/apps/tx-builder/src/components/Icon/images/home.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/knowledge.tsx b/apps/tx-builder/src/components/Icon/images/knowledge.tsx deleted file mode 100644 index bcf22aa97..000000000 --- a/apps/tx-builder/src/components/Icon/images/knowledge.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/licenses.tsx b/apps/tx-builder/src/components/Icon/images/licenses.tsx deleted file mode 100644 index ced0f3f21..000000000 --- a/apps/tx-builder/src/components/Icon/images/licenses.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/loadSafe.tsx b/apps/tx-builder/src/components/Icon/images/loadSafe.tsx deleted file mode 100644 index 32de0a881..000000000 --- a/apps/tx-builder/src/components/Icon/images/loadSafe.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/locked.tsx b/apps/tx-builder/src/components/Icon/images/locked.tsx deleted file mode 100644 index a653e04cf..000000000 --- a/apps/tx-builder/src/components/Icon/images/locked.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx b/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx deleted file mode 100644 index 499bd6e25..000000000 --- a/apps/tx-builder/src/components/Icon/images/mobileConfirm.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/noInternet.tsx b/apps/tx-builder/src/components/Icon/images/noInternet.tsx deleted file mode 100644 index 790145e5a..000000000 --- a/apps/tx-builder/src/components/Icon/images/noInternet.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/owners.tsx b/apps/tx-builder/src/components/Icon/images/owners.tsx deleted file mode 100644 index 318c96344..000000000 --- a/apps/tx-builder/src/components/Icon/images/owners.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/paste.tsx b/apps/tx-builder/src/components/Icon/images/paste.tsx deleted file mode 100644 index 5adbf45fd..000000000 --- a/apps/tx-builder/src/components/Icon/images/paste.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/paymentToken.tsx b/apps/tx-builder/src/components/Icon/images/paymentToken.tsx deleted file mode 100644 index 13d59aa83..000000000 --- a/apps/tx-builder/src/components/Icon/images/paymentToken.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx b/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx deleted file mode 100644 index 4665d6be2..000000000 --- a/apps/tx-builder/src/components/Icon/images/privacyPolicy.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/qrCode.tsx b/apps/tx-builder/src/components/Icon/images/qrCode.tsx deleted file mode 100644 index 42617ab42..000000000 --- a/apps/tx-builder/src/components/Icon/images/qrCode.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/question.tsx b/apps/tx-builder/src/components/Icon/images/question.tsx deleted file mode 100644 index 54f118c8c..000000000 --- a/apps/tx-builder/src/components/Icon/images/question.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/rateApp.tsx b/apps/tx-builder/src/components/Icon/images/rateApp.tsx deleted file mode 100644 index da0641758..000000000 --- a/apps/tx-builder/src/components/Icon/images/rateApp.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/received.tsx b/apps/tx-builder/src/components/Icon/images/received.tsx deleted file mode 100644 index e7e95260d..000000000 --- a/apps/tx-builder/src/components/Icon/images/received.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/recover.tsx b/apps/tx-builder/src/components/Icon/images/recover.tsx deleted file mode 100644 index 488890655..000000000 --- a/apps/tx-builder/src/components/Icon/images/recover.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx b/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx deleted file mode 100644 index 4c2b440a2..000000000 --- a/apps/tx-builder/src/components/Icon/images/replaceOwner.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx b/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx deleted file mode 100644 index 0ed5525a9..000000000 --- a/apps/tx-builder/src/components/Icon/images/requiredConfirmations.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/restricted.tsx b/apps/tx-builder/src/components/Icon/images/restricted.tsx deleted file mode 100644 index 21591162c..000000000 --- a/apps/tx-builder/src/components/Icon/images/restricted.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/resync.tsx b/apps/tx-builder/src/components/Icon/images/resync.tsx deleted file mode 100644 index 5164b6b6a..000000000 --- a/apps/tx-builder/src/components/Icon/images/resync.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/rocket.tsx b/apps/tx-builder/src/components/Icon/images/rocket.tsx deleted file mode 100644 index b4f6bbbaa..000000000 --- a/apps/tx-builder/src/components/Icon/images/rocket.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/safe.tsx b/apps/tx-builder/src/components/Icon/images/safe.tsx deleted file mode 100644 index e01a52a16..000000000 --- a/apps/tx-builder/src/components/Icon/images/safe.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/scan.tsx b/apps/tx-builder/src/components/Icon/images/scan.tsx deleted file mode 100644 index 612b95aff..000000000 --- a/apps/tx-builder/src/components/Icon/images/scan.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/search.tsx b/apps/tx-builder/src/components/Icon/images/search.tsx deleted file mode 100644 index 1034e83f5..000000000 --- a/apps/tx-builder/src/components/Icon/images/search.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/sendAgain.tsx b/apps/tx-builder/src/components/Icon/images/sendAgain.tsx deleted file mode 100644 index c935cb835..000000000 --- a/apps/tx-builder/src/components/Icon/images/sendAgain.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/sent.tsx b/apps/tx-builder/src/components/Icon/images/sent.tsx deleted file mode 100644 index 4279522c8..000000000 --- a/apps/tx-builder/src/components/Icon/images/sent.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/serverError.tsx b/apps/tx-builder/src/components/Icon/images/serverError.tsx deleted file mode 100644 index 6bbd6f5ba..000000000 --- a/apps/tx-builder/src/components/Icon/images/serverError.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/settings.tsx b/apps/tx-builder/src/components/Icon/images/settings.tsx deleted file mode 100644 index 8b4829127..000000000 --- a/apps/tx-builder/src/components/Icon/images/settings.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/settingsChange.tsx b/apps/tx-builder/src/components/Icon/images/settingsChange.tsx deleted file mode 100644 index c018296b3..000000000 --- a/apps/tx-builder/src/components/Icon/images/settingsChange.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/settingsTool.tsx b/apps/tx-builder/src/components/Icon/images/settingsTool.tsx deleted file mode 100644 index 9cee1412e..000000000 --- a/apps/tx-builder/src/components/Icon/images/settingsTool.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/share.tsx b/apps/tx-builder/src/components/Icon/images/share.tsx deleted file mode 100644 index cd21a60cb..000000000 --- a/apps/tx-builder/src/components/Icon/images/share.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx b/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx deleted file mode 100644 index ac428ef2a..000000000 --- a/apps/tx-builder/src/components/Icon/images/transactionsInactive.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/unlocked.tsx b/apps/tx-builder/src/components/Icon/images/unlocked.tsx deleted file mode 100644 index 1e8c56fda..000000000 --- a/apps/tx-builder/src/components/Icon/images/unlocked.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - - ), - md: ( - - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/userEdit.tsx b/apps/tx-builder/src/components/Icon/images/userEdit.tsx deleted file mode 100644 index 8f649e7d7..000000000 --- a/apps/tx-builder/src/components/Icon/images/userEdit.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} diff --git a/apps/tx-builder/src/components/Icon/images/wallet.tsx b/apps/tx-builder/src/components/Icon/images/wallet.tsx deleted file mode 100644 index f40ed2544..000000000 --- a/apps/tx-builder/src/components/Icon/images/wallet.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -export default { - sm: ( - - - - - - - ), - md: ( - - - - - - - ), -} From a8d98d693594bc52019accfcfa05f14986ad1444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Fri, 4 Oct 2024 11:20:43 +0200 Subject: [PATCH 3/5] feat(tx-builder-components): move necessary components from react-component library to tx-builder --- .../src/components/Accordion/index.tsx | 87 +++ apps/tx-builder/src/components/Button.tsx | 208 +++++++ apps/tx-builder/src/components/Card/index.tsx | 36 ++ apps/tx-builder/src/components/Divider.tsx | 29 + apps/tx-builder/src/components/Dot/index.tsx | 24 + .../tx-builder/src/components/ETHHashInfo.tsx | 149 +++++ .../src/components/EllipsisMenu/index.tsx | 102 ++++ .../src/components/GenericModal.tsx | 121 ++++ apps/tx-builder/src/components/Link/index.tsx | 21 + .../src/components/Loader/index.tsx | 34 ++ apps/tx-builder/src/components/Switch.tsx | 46 ++ apps/tx-builder/src/components/Text.tsx | 66 +++ apps/tx-builder/src/components/Title.tsx | 72 +++ apps/tx-builder/src/components/Tooltip.tsx | 110 ++++ .../components/buttons/ButtonLink/index.tsx | 52 ++ .../CopyToClipboardBtn/copyTextToClipboard.ts | 24 + .../buttons/CopyToClipboardBtn/index.tsx | 78 +++ .../buttons/ExplorerButton/index.tsx | 59 ++ .../components/buttons/Identicon/index.tsx | 32 ++ .../components/forms/fields/AddressInput.tsx | 208 +++++++ .../forms/fields/TextFieldInput.tsx | 57 ++ .../src/components/forms/fields/styles.ts | 118 ++++ apps/tx-builder/src/hooks/useDebounce.ts | 14 + apps/tx-builder/src/hooks/useThrottle.ts | 26 + .../src/theme/SafeThemeProvider.tsx | 17 + apps/tx-builder/src/theme/lightPalette.ts | 65 +++ apps/tx-builder/src/theme/safeTheme.ts | 520 ++++++++++++++++++ apps/tx-builder/src/theme/typography.ts | 50 ++ apps/tx-builder/src/utils/address.ts | 59 ++ apps/tx-builder/src/utils/strings.ts | 25 + 30 files changed, 2509 insertions(+) create mode 100644 apps/tx-builder/src/components/Accordion/index.tsx create mode 100644 apps/tx-builder/src/components/Button.tsx create mode 100644 apps/tx-builder/src/components/Card/index.tsx create mode 100644 apps/tx-builder/src/components/Divider.tsx create mode 100644 apps/tx-builder/src/components/Dot/index.tsx create mode 100644 apps/tx-builder/src/components/ETHHashInfo.tsx create mode 100644 apps/tx-builder/src/components/EllipsisMenu/index.tsx create mode 100644 apps/tx-builder/src/components/GenericModal.tsx create mode 100644 apps/tx-builder/src/components/Link/index.tsx create mode 100644 apps/tx-builder/src/components/Loader/index.tsx create mode 100644 apps/tx-builder/src/components/Switch.tsx create mode 100644 apps/tx-builder/src/components/Text.tsx create mode 100644 apps/tx-builder/src/components/Title.tsx create mode 100644 apps/tx-builder/src/components/Tooltip.tsx create mode 100644 apps/tx-builder/src/components/buttons/ButtonLink/index.tsx create mode 100644 apps/tx-builder/src/components/buttons/CopyToClipboardBtn/copyTextToClipboard.ts create mode 100644 apps/tx-builder/src/components/buttons/CopyToClipboardBtn/index.tsx create mode 100644 apps/tx-builder/src/components/buttons/ExplorerButton/index.tsx create mode 100644 apps/tx-builder/src/components/buttons/Identicon/index.tsx create mode 100644 apps/tx-builder/src/components/forms/fields/AddressInput.tsx create mode 100644 apps/tx-builder/src/components/forms/fields/TextFieldInput.tsx create mode 100644 apps/tx-builder/src/components/forms/fields/styles.ts create mode 100644 apps/tx-builder/src/hooks/useDebounce.ts create mode 100644 apps/tx-builder/src/hooks/useThrottle.ts create mode 100644 apps/tx-builder/src/theme/SafeThemeProvider.tsx create mode 100644 apps/tx-builder/src/theme/lightPalette.ts create mode 100644 apps/tx-builder/src/theme/safeTheme.ts create mode 100644 apps/tx-builder/src/theme/typography.ts create mode 100644 apps/tx-builder/src/utils/address.ts create mode 100644 apps/tx-builder/src/utils/strings.ts diff --git a/apps/tx-builder/src/components/Accordion/index.tsx b/apps/tx-builder/src/components/Accordion/index.tsx new file mode 100644 index 000000000..36fc14311 --- /dev/null +++ b/apps/tx-builder/src/components/Accordion/index.tsx @@ -0,0 +1,87 @@ +import { ReactElement } from 'react' +import AccordionMUI, { AccordionProps as AccordionMUIProps } from '@material-ui/core/Accordion' +import AccordionSummaryMUI, { + AccordionSummaryProps as AccordionSummaryMUIProps, +} from '@material-ui/core/AccordionSummary' +import styled from 'styled-components' +import FixedIcon from '../FixedIcon' + +type AccordionProps = AccordionMUIProps & { + compact?: boolean +} + +type StyledAccordionProps = AccordionMUIProps & { + $compact?: AccordionProps['compact'] +} + +const StyledAccordion = styled(AccordionMUI)` + &.MuiAccordion-root { + border-radius: ${({ $compact }) => ($compact ? '8px' : '0')}; + border: ${({ $compact, theme }) => ($compact ? '2px solid ' + theme.palette.divider : 'none')}; + border-bottom: 2px solid ${({ theme }) => theme.palette.divider}; + margin-bottom: ${({ $compact }) => ($compact ? '16px' : '0')}; + overflow: hidden; + + &:before { + height: 0; + } + + &:first-child { + border-top: 2px solid ${({ theme }) => theme.palette.divider}; + } + + &.Mui-expanded { + margin: ${({ $compact }) => ($compact ? '0 0 16px 0' : '0')}; + } + + .MuiAccordionDetails-root { + padding: 16px; + } + } +` + +const StyledAccordionSummary = styled(AccordionSummaryMUI)` + &.MuiAccordionSummary-root { + &.Mui-expanded { + min-height: 48px; + border-bottom: 2px solid ${({ theme }) => theme.palette.divider}; + background-color: ${({ theme }) => theme.palette.background.default}; + } + + &:hover { + background-color: ${({ theme }) => theme.palette.background.default}; + } + + .MuiAccordionSummary-content { + &.Mui-expanded { + margin: 0; + } + } + .MuiIconButton-root { + font-size: 0; + padding: 16px; + } + } +` + +export const Accordion = ({ compact, children, ...props }: AccordionProps): ReactElement => { + return ( + + {children} + + ) +} + +export const AccordionSummary = ({ + children, + ...props +}: AccordionSummaryMUIProps): ReactElement => { + return ( + } {...props}> + {children} + + ) +} + +export { default as AccordionActions } from '@material-ui/core/AccordionActions' +export { default as AccordionDetails } from '@material-ui/core/AccordionDetails' diff --git a/apps/tx-builder/src/components/Button.tsx b/apps/tx-builder/src/components/Button.tsx new file mode 100644 index 000000000..50075d132 --- /dev/null +++ b/apps/tx-builder/src/components/Button.tsx @@ -0,0 +1,208 @@ +import React, { ReactElement, ReactNode, HTMLAttributes } from 'react' +import ButtonMUI, { ButtonProps as ButtonMUIProps } from '@material-ui/core/Button' +import { alpha } from '@material-ui/core/styles' + +import styled, { css, DefaultTheme, FlattenInterpolation, ThemeProps } from 'styled-components' +import { Icon, IconProps } from './Icon' + +type Colors = 'primary' | 'secondary' | 'error' +type Variations = 'bordered' | 'contained' | 'outlined' + +type CustomButtonMuiProps = Omit & { + to?: string + component?: ReactNode +} +type LocalProps = { + children?: ReactNode + color?: Colors + variant?: Variations + iconType?: IconProps['type'] + iconSize?: IconProps['size'] +} + +type Props = LocalProps & CustomButtonMuiProps & HTMLAttributes + +const StyledIcon = styled(Icon)` + margin-right: 5px; +` + +const customStyles: { + [key in Colors]: { + [key in Variations]: FlattenInterpolation> + } +} = { + primary: { + contained: css` + color: ${({ theme }) => theme.palette.common.white}; + background-color: ${({ theme }) => theme.palette.primary.main}; + box-shadow: 1px 2px 10px ${alpha('#28363D', 0.18)}; + + &:hover { + color: ${({ theme }) => theme.palette.common.white}; + background-color: ${({ theme }) => theme.palette.primary.dark}; + } + `, + outlined: css` + color: ${({ theme }) => theme.palette.primary.main}; + background-color: transparent; + path.icon-color { + fill: ${({ theme }) => theme.palette.primary.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.primary.main}; + } + + &:hover { + color: ${({ theme }) => theme.palette.primary.dark}; + } + `, + bordered: css` + color: ${({ theme }) => theme.palette.primary.main}; + background-color: transparent; + border: 2px solid ${({ theme }) => theme.palette.primary.main}; + path.icon-color { + fill: ${({ theme }) => theme.palette.primary.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.primary.main}; + } + + &:hover { + background: ${({ theme }) => theme.palette.background.light}; + } + `, + }, + secondary: { + contained: css` + color: ${({ theme }) => theme.palette.primary}; + background-color: ${({ theme }) => theme.palette.secondary.main}; + box-shadow: 1px 2px 10px ${alpha('#28363D', 0.18)}; + + path.icon-color { + color: ${({ theme }) => theme.palette.common.primary}; + } + + &:hover { + path.icon-color { + color: ${({ theme }) => theme.palette.common.primary}; + } + + background-color: ${({ theme }) => theme.palette.secondary.dark}; + } + `, + outlined: css` + color: ${({ theme }) => theme.palette.secondary.main}; + background-color: transparent; + path.icon-color { + fill: ${({ theme }) => theme.palette.secondary.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.secondary.main}; + } + `, + bordered: css` + color: ${({ theme }) => theme.palette.secondary.main}; + background-color: transparent; + border: 2px solid ${({ theme }) => theme.palette.secondary.main}; + path.icon-color { + fill: ${({ theme }) => theme.palette.secondary.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.secondary.main}; + } + `, + }, + error: { + contained: css` + color: ${({ theme }) => theme.palette.error.main}; + background-color: ${({ theme }) => theme.palette.error.background}; + + &:hover { + background-color: ${({ theme }) => theme.palette.error.light}; + color: ${({ theme }) => theme.palette.error.dark}; + } + `, + outlined: css` + color: ${({ theme }) => theme.palette.error.main}; + background-color: transparent; + path.icon-color { + fill: ${({ theme }) => theme.palette.error.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.error.main}; + } + `, + bordered: css` + color: ${({ theme }) => theme.palette.error.main}; + background-color: transparent; + border: 2px solid ${({ theme }) => theme.palette.error.main}; + path.icon-color { + fill: ${({ theme }) => theme.palette.error.main}; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.error.main}; + } + `, + }, +} + +const StyledButton = styled(ButtonMUI)<{ $localProps: LocalProps }>` + && { + font-weight: 700; + padding: 8px 1.4rem; + min-width: 120px; + + &.MuiButton-root { + text-transform: none; + border-radius: 8px; + letter-spacing: 0; + } + + &.Mui-disabled { + color: ${({ theme }) => theme.palette.common.white}; + } + + path.icon-color { + fill: ${({ theme }) => theme.palette.common.white}; + } + + &:disabled { + opacity: 0.5; + } + + ${({ $localProps }) => { + if ($localProps.color !== undefined && $localProps.variant !== undefined) { + return customStyles[$localProps.color][$localProps.variant] + } + }} + } +` + +const Button = ({ + children, + color = 'primary', + variant = 'contained', + iconType, + iconSize, + // We need destructuring all LocalProps, remaining props are for CustomButtonMuiProps + ...buttonMuiProps +}: Props): ReactElement => { + return ( + + {iconType && iconSize && } + {children} + + ) +} + +export default Button diff --git a/apps/tx-builder/src/components/Card/index.tsx b/apps/tx-builder/src/components/Card/index.tsx new file mode 100644 index 000000000..83f161ce1 --- /dev/null +++ b/apps/tx-builder/src/components/Card/index.tsx @@ -0,0 +1,36 @@ +import React from 'react' +import styled from 'styled-components' +import { alpha } from '@material-ui/core/styles' + +const StyledCard = styled.div` + box-shadow: 1px 2px 10px 0 ${alpha('#28363D', 0.18)}; + border-radius: 8px; + padding: 24px; + background-color: ${({ theme }) => theme.palette.common.white}; + position: relative; +` + +const Disabled = styled.div` + opacity: 0.5; + position: absolute; + height: 100%; + width: 100%; + background-color: ${({ theme }) => theme.palette.common.white}; + z-index: 1; + top: 0; + left: 0; +` + +type Props = { + className?: string + disabled?: boolean +} & React.HTMLAttributes + +const Card: React.FC = ({ className, children, disabled, ...rest }): React.ReactElement => ( + + {disabled && } + {children} + +) + +export default Card diff --git a/apps/tx-builder/src/components/Divider.tsx b/apps/tx-builder/src/components/Divider.tsx new file mode 100644 index 000000000..93c28df38 --- /dev/null +++ b/apps/tx-builder/src/components/Divider.tsx @@ -0,0 +1,29 @@ +import React from 'react' +import styled from 'styled-components' + +type Props = { + className?: string + orientation?: 'vertical' | 'horizontal' +} + +const HorizontalDivider = styled.div` + margin: 16px -1.6rem; + border-top: solid 1px #dcdee0; + width: calc(100% + 3.2rem); +` + +const VerticalDivider = styled.div` + border-right: 1px solid ${({ theme }) => theme.legacy.colors.separator}; + margin: 0 5px; + height: 100%; +` + +const Divider = ({ className, orientation }: Props): React.ReactElement => { + return orientation === 'vertical' ? ( + + ) : ( + + ) +} + +export default Divider diff --git a/apps/tx-builder/src/components/Dot/index.tsx b/apps/tx-builder/src/components/Dot/index.tsx new file mode 100644 index 000000000..df53a5643 --- /dev/null +++ b/apps/tx-builder/src/components/Dot/index.tsx @@ -0,0 +1,24 @@ +import React from 'react' +import styled from 'styled-components' +import { type Theme } from '@material-ui/core/styles' + +type Props = { + className?: string + color: keyof Theme['palette'] +} + +const StyledDot = styled.div` + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + height: 36px; + width: 36px; + background-color: ${({ theme, color }) => theme.palette[color].main}; +` + +const Dot: React.FC = ({ children, ...rest }): React.ReactElement => ( + {children} +) + +export default Dot diff --git a/apps/tx-builder/src/components/ETHHashInfo.tsx b/apps/tx-builder/src/components/ETHHashInfo.tsx new file mode 100644 index 000000000..e03611de0 --- /dev/null +++ b/apps/tx-builder/src/components/ETHHashInfo.tsx @@ -0,0 +1,149 @@ +import React, { useState } from 'react' +import styled from 'styled-components' + +import { BreakpointDefaults } from '@material-ui/core/styles/createBreakpoints' +import { textShortener } from '../utils/strings' +import { EllipsisMenuItem } from '@gnosis.pm/safe-react-components' +import Text from './Text' +import { Theme } from '@material-ui/core' +import ExplorerButton from './buttons/ExplorerButton' +import Identicon, { identiconSizes } from './buttons/Identicon' +import CopyToClipboardBtn from './buttons/CopyToClipboardBtn' +import EllipsisMenu from './EllipsisMenu' + +export type ExplorerInfo = () => { url: string; alt: string } + +const StyledContainer = styled.div` + display: flex; + align-items: center; +` + +const AvatarContainer = styled.div` + display: flex; + margin-right: 8px; +` + +const InfoContainer = styled.div` + display: flex; + align-items: flex-start; + justify-content: center; + flex-direction: column; +` + +const AddressContainer = styled.div` + display: flex; + align-items: center; + gap: 4px; +` + +const StyledImg = styled.img<{ size: keyof typeof identiconSizes }>` + height: ${({ size }) => identiconSizes[size]}; + width: ${({ size }) => identiconSizes[size]}; +` + +type Props = { + className?: string + hash: string + showHash?: boolean + shortenHash?: number + name?: string + strongName?: boolean + textColor?: keyof Theme['palette'] + textSize?: keyof BreakpointDefaults + showAvatar?: boolean + customAvatar?: string + customAvatarFallback?: string + avatarSize?: keyof BreakpointDefaults + showCopyBtn?: boolean + menuItems?: EllipsisMenuItem[] + explorerUrl?: ExplorerInfo +} + +type ShortNameProps = + | { + shouldShowShortName: boolean + shouldCopyShortName?: boolean + shortName: string + } + | { + shouldShowShortName?: boolean + shouldCopyShortName: boolean + shortName: string + } + | { + shouldShowShortName?: never + shouldCopyShortName?: never + shortName?: string + } + +type EthHashInfoProps = Props & ShortNameProps + +const EthHashInfo = ({ + hash, + showHash = true, + name, + className, + shortenHash, + showAvatar, + customAvatar, + customAvatarFallback, + avatarSize = 'md', + showCopyBtn, + menuItems, + explorerUrl, + shortName, + shouldShowShortName, + shouldCopyShortName, +}: EthHashInfoProps): React.ReactElement => { + const [fallbackToIdenticon, setFallbackToIdenticon] = useState(false) + const [fallbackSrc, setFallabckSrc] = useState(undefined) + + const setAppImageFallback = (): void => { + if (customAvatarFallback && !fallbackToIdenticon) { + setFallabckSrc(customAvatarFallback) + } else { + setFallbackToIdenticon(true) + } + } + + return ( + + {showAvatar && ( + + {!fallbackToIdenticon && customAvatar ? ( + + ) : ( + + )} + + )} + + + {name && {name}} + + {showHash && ( + + {shouldShowShortName && ( + + {shortName}: + + )} + {shortenHash ? textShortener(hash, shortenHash + 2, shortenHash) : hash} + + )} + {showCopyBtn && ( + + )} + {explorerUrl && } + {menuItems && } + + + + ) +} + +export default EthHashInfo diff --git a/apps/tx-builder/src/components/EllipsisMenu/index.tsx b/apps/tx-builder/src/components/EllipsisMenu/index.tsx new file mode 100644 index 000000000..ff563b512 --- /dev/null +++ b/apps/tx-builder/src/components/EllipsisMenu/index.tsx @@ -0,0 +1,102 @@ +import { ClickAwayListener } from '@material-ui/core' +import Menu from '@material-ui/core/Menu' +import MenuItem from '@material-ui/core/MenuItem' +import React from 'react' +import styled from 'styled-components' +import FixedIcon from '../FixedIcon' + +const StyledMenu = styled(Menu)` + && { + .MuiMenu-paper { + box-shadow: 0 0 4px rgba(0, 0, 0, 0.1); + } + + .MuiMenu-list { + div:not(:first-child) { + border-top: 1px solid ${({ theme }) => theme.palette.divider}; + } + } + } +` + +const MenuWrapper = styled.div` + display: flex; +` + +const MenuItemWrapper = styled.div` + :focus { + outline-color: ${({ theme }) => theme.palette.divider}; + } +` + +const IconWrapper = styled.button` + background: none; + border: none; + cursor: pointer; + margin: 0; + border-radius: 50%; + transition: background-color 0.2s ease-in-out; + outline-color: transparent; + height: 24px; + width: 24px; + + span { + display: flex; + } + + :hover { + background-color: ${({ theme }) => theme.palette.divider}; + } +` + +export type EllipsisMenuItem = { + label: string + disabled?: boolean + onClick: () => void +} + +type Props = { + menuItems: EllipsisMenuItem[] +} + +const EllipsisMenu = ({ menuItems }: Props): React.ReactElement => { + const [anchorEl, setAnchorEl] = React.useState(null) + + const handleClick = (event: React.MouseEvent): void => + setAnchorEl(event.currentTarget) + + const closeMenuHandler = () => { + setAnchorEl(null) + } + + const onMenuItemClick = (item: EllipsisMenuItem) => { + item.onClick() + closeMenuHandler() + } + + return ( + + + + + + + {menuItems.map(item => ( + + onMenuItemClick(item)}> + {item.label} + + + ))} + + + + ) +} + +export default EllipsisMenu diff --git a/apps/tx-builder/src/components/GenericModal.tsx b/apps/tx-builder/src/components/GenericModal.tsx new file mode 100644 index 000000000..d0f15d527 --- /dev/null +++ b/apps/tx-builder/src/components/GenericModal.tsx @@ -0,0 +1,121 @@ +import React from 'react' +import Modal from '@material-ui/core/Modal' +import { makeStyles } from '@material-ui/core/styles' +import { alpha } from '@material-ui/core/styles' +import styled from 'styled-components' +import Media from 'react-media' +import { defaultTheme } from '../theme/safeTheme' +import { Typography } from '@material-ui/core' +import { Icon } from './Icon' + +const StyledButton = styled.button` + background: none; + border: none; + padding: 5px; + width: 26px; + height: 26px; + + span { + margin-right: 0; + } + + :focus { + outline: none; + } + + :hover { + background: ${({ theme }) => theme.palette.divider}; + border-radius: 16px; + } +` + +const TitleSection = styled.div` + display: flex; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 2px solid ${({ theme }) => theme.palette.divider}; +` + +const BodySection = styled.div<{ + withoutBodyPadding?: boolean + smallHeight: boolean +}>` + max-height: ${({ smallHeight }) => (smallHeight ? '280px' : '460px')}; + overflow-y: auto; + padding: ${({ withoutBodyPadding }) => (withoutBodyPadding ? '0' : '16px 24px')}; +` + +const FooterSection = styled.div` + border-top: 2px solid ${({ theme }) => theme.palette.divider}; + padding: 16px 24px; +` + +export type GenericModalProps = { + title: string | React.ReactNode + body: React.ReactNode + withoutBodyPadding?: boolean + footer?: React.ReactNode + onClose: () => void +} + +const useStyles = makeStyles({ + modal: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + overflowY: 'scroll', + background: alpha('#E8E7E6', 0.75), + }, + + paper: { + position: (props: { smallHeight: boolean }) => (props.smallHeight ? 'relative' : 'absolute'), + top: (props: { smallHeight: boolean }) => (props.smallHeight ? 'unset' : '121px'), + minWidth: '500px', + width: (props: { smallHeight: boolean }) => (props.smallHeight ? '500px' : 'inherit'), + backgroundColor: defaultTheme.palette.common.white, + borderRadius: '8px', + boxShadow: `0 0 0.75 0 #28363D`, + + '&:focus': { + outline: 'none', + }, + }, +}) + +const GenericModalComponent = ({ + body, + footer, + onClose, + title, + withoutBodyPadding, + smallHeight, +}: GenericModalProps & { smallHeight: boolean }) => { + const classes = useStyles({ smallHeight }) + + return ( + +
+ + {title} + + + + + + + {body} + + + {footer && {footer}} +
+
+ ) +} + +const GenericModal = (props: GenericModalProps): React.ReactElement => ( + + {matches => } + +) + +export default GenericModal diff --git a/apps/tx-builder/src/components/Link/index.tsx b/apps/tx-builder/src/components/Link/index.tsx new file mode 100644 index 000000000..444fb3df8 --- /dev/null +++ b/apps/tx-builder/src/components/Link/index.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import styled from 'styled-components' +import { type Theme } from '@material-ui/core/styles' + +export interface Props extends React.AnchorHTMLAttributes { + color?: keyof Theme['palette'] | 'white' +} + +const StyledLink = styled.a` + cursor: pointer; + color: ${({ theme, color = 'primary' }) => + color === 'white' ? theme.palette.common.white : theme.palette[color].dark}; + font-family: ${({ theme }) => theme.typography.fontFamily}; + text-decoration: underline; +` + +const Link: React.FC = ({ children, ...rest }): React.ReactElement => { + return {children} +} + +export default Link diff --git a/apps/tx-builder/src/components/Loader/index.tsx b/apps/tx-builder/src/components/Loader/index.tsx new file mode 100644 index 000000000..c0e6d75bf --- /dev/null +++ b/apps/tx-builder/src/components/Loader/index.tsx @@ -0,0 +1,34 @@ +import React from 'react' +import styled from 'styled-components' +import CircularProgress from '@material-ui/core/CircularProgress' +import { type Theme } from '@material-ui/core/styles' + +const loaderSizes = { + xxs: '10px', + xs: '16px', + sm: '30px', + md: '50px', + lg: '70px', +} + +type Props = { + size: keyof typeof loaderSizes + color?: keyof Theme['palette'] + className?: string +} + +const StyledCircularProgress = styled( + ({ size, className }: Props): React.ReactElement => ( + + ), +)` + &.MuiCircularProgress-colorPrimary { + color: ${({ theme, color = 'primary' }) => theme.palette[color].main}; + } +` + +const Loader = ({ className, size, color }: Props): React.ReactElement => ( + +) + +export default Loader diff --git a/apps/tx-builder/src/components/Switch.tsx b/apps/tx-builder/src/components/Switch.tsx new file mode 100644 index 000000000..bb027a508 --- /dev/null +++ b/apps/tx-builder/src/components/Switch.tsx @@ -0,0 +1,46 @@ +import React from 'react' +import SwitchMui from '@material-ui/core/Switch' +import styled from 'styled-components' +import { alpha } from '@material-ui/core/styles' + +const StyledSwitch = styled(({ ...rest }) => )` + && { + .MuiSwitch-thumb { + background: ${({ theme, checked }) => + checked ? theme.palette.secondary.main : theme.palette.common.white}; + box-shadow: + 1px 1px 2px rgba(0, 0, 0, 0.2), + 0 0 1px rgba(0, 0, 0, 0.5); + } + + .MuiSwitch-track { + background: ${({ theme }) => theme.palette.common.black}; + } + + .MuiIconButton-label, + .MuiSwitch-colorSecondary.Mui-checked { + color: ${({ checked, theme }) => (checked ? theme.palette.secondary.dark : '#B2B5B2')}; + } + + .MuiSwitch-colorSecondary.Mui-checked:hover { + background-color: ${({ theme }) => alpha(theme.palette.secondary.dark, 0.08)}; + } + + .Mui-checked + .MuiSwitch-track { + background-color: ${({ theme }) => theme.palette.secondary.dark}; + } + } +` + +type Props = { + checked: boolean + onChange: (checked: boolean) => void +} + +const Switch = ({ checked, onChange }: Props): React.ReactElement => { + const onSwitchChange = (_event: any, checked: boolean) => onChange(checked) + + return +} + +export default Switch diff --git a/apps/tx-builder/src/components/Text.tsx b/apps/tx-builder/src/components/Text.tsx new file mode 100644 index 000000000..ea4cb5674 --- /dev/null +++ b/apps/tx-builder/src/components/Text.tsx @@ -0,0 +1,66 @@ +import React from 'react' +import Tooltip from '@material-ui/core/Tooltip' +import { withStyles, alpha } from '@material-ui/core/styles' +import { type Theme } from '@material-ui/core/styles' + +import { Typography, TypographyProps } from '@material-ui/core' +import styled from 'styled-components' + +type Props = { + children: React.ReactNode + tooltip?: string + color?: keyof Theme['palette'] | 'white' + className?: string + component?: 'span' | 'p' + strong?: boolean + center?: boolean +} + +const StyledTooltip = withStyles(theme => ({ + tooltip: { + backgroundColor: theme.palette.common.white, + color: theme.palette.text.primary, + boxShadow: `0px 0px 10px ${alpha('#28363D', 0.2)}`, + }, + arrow: { + color: theme.palette.common.white, + boxShadow: 'transparent', + }, +}))(Tooltip) + +const StyledTypography = styled(Typography)<{ $color?: keyof Theme['palette'] | 'white' } & Props>` + color: ${({ $color, theme }) => + $color + ? $color === 'white' + ? theme.palette.common.white + : theme.palette[$color].main + : theme.palette.primary.main}; + + ${({ center }) => center && 'text-align: center;'} + + ${({ strong }) => strong && `font-weight: bold;`} +` + +const Text = ({ + children, + component = 'p', + tooltip, + color, + ...rest +}: Props & Omit): React.ReactElement => { + const TextElement = ( + + {children} + + ) + + return tooltip === undefined ? ( + TextElement + ) : ( + + {TextElement} + + ) +} + +export default Text diff --git a/apps/tx-builder/src/components/Title.tsx b/apps/tx-builder/src/components/Title.tsx new file mode 100644 index 000000000..7600e6c20 --- /dev/null +++ b/apps/tx-builder/src/components/Title.tsx @@ -0,0 +1,72 @@ +import { BreakpointDefaults } from '@material-ui/core/styles/createBreakpoints' +import React from 'react' +import styled from 'styled-components' + +type Props = { + children: string | React.ReactNode + size: keyof BreakpointDefaults + withoutMargin?: boolean + strong?: boolean +} + +const StyledH1 = styled.h1<{ withoutMargin?: boolean; strong?: boolean }>` + font-family: ${({ theme }) => theme.legacy.fonts.fontFamily}; + font-size: ${({ theme }) => theme.legacy.title.size.xl.fontSize}; + line-height: ${({ theme }) => theme.legacy.title.size.xl.lineHeight}; + font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')}; + margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '30px')} 0; +` + +const StyledH2 = styled.h2<{ withoutMargin?: boolean; strong?: boolean }>` + font-family: ${({ theme }) => theme.legacy.fonts.fontFamily}; + font-size: ${({ theme }) => theme.legacy.title.size.lg.fontSize}; + line-height: ${({ theme }) => theme.legacy.title.size.lg.lineHeight}; + font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')}; + margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '28px')} 0; +` + +const StyledH3 = styled.h3<{ withoutMargin?: boolean; strong?: boolean }>` + font-family: ${({ theme }) => theme.legacy.fonts.fontFamily}; + font-size: ${({ theme }) => theme.legacy.title.size.md.fontSize}; + line-height: ${({ theme }) => theme.legacy.title.size.md.lineHeight}; + font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')}; + margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '26px')} 0; +` + +const StyledH4 = styled.h4<{ withoutMargin?: boolean; strong?: boolean }>` + font-family: ${({ theme }) => theme.legacy.fonts.fontFamily}; + font-size: ${({ theme }) => theme.legacy.title.size.sm.fontSize}; + line-height: ${({ theme }) => theme.legacy.title.size.sm.lineHeight}; + font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')}; + margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '22px')} 0; +` + +const StyledH5 = styled.h5<{ withoutMargin?: boolean; strong?: boolean }>` + font-family: ${({ theme }) => theme.legacy.fonts.fontFamily}; + font-size: ${({ theme }) => theme.legacy.title.size.xs.fontSize}; + line-height: ${({ theme }) => theme.legacy.title.size.xs.lineHeight}; + font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')}; + margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '18px')} 0; +` + +const Title = ({ children, size, ...rest }: Props) => { + switch (size) { + case 'xl': { + return {children} + } + case 'lg': { + return {children} + } + case 'md': { + return {children} + } + case 'sm': { + return {children} + } + case 'xs': { + return {children} + } + } +} + +export default Title diff --git a/apps/tx-builder/src/components/Tooltip.tsx b/apps/tx-builder/src/components/Tooltip.tsx new file mode 100644 index 000000000..62cc86cd5 --- /dev/null +++ b/apps/tx-builder/src/components/Tooltip.tsx @@ -0,0 +1,110 @@ +import { ReactElement } from 'react' +import MUITooltip, { TooltipProps as TooltipPropsMui } from '@material-ui/core/Tooltip' +import { withStyles, alpha, type Theme } from '@material-ui/core/styles' +import { BreakpointDefaults } from '@material-ui/core/styles/createBreakpoints' +import { PaletteColor } from '@material-ui/core/styles/createPalette' + +type TooltipProps = { + size?: keyof BreakpointDefaults + backgroundColor?: keyof Theme['palette'] + textColor?: keyof Theme['palette'] + padding?: string + border?: string +} + +const getPaddingBySize = (size: keyof BreakpointDefaults): string => { + switch (size) { + case 'lg': + return '8px 16px' + default: + return '4px 8px' + } +} + +const getBorderBySize = (size: keyof BreakpointDefaults): string => { + switch (size) { + case 'lg': + return 'none' + default: + return `1px solid #B2B5B2` + } +} + +const getFontInfoBySize = ( + size: keyof BreakpointDefaults, +): { + fontSize: string + lineHeight: string +} => { + switch (size) { + case 'lg': + return { + fontSize: '14px', + lineHeight: '20px', + } + default: + return { + fontSize: '12px', + lineHeight: '16px', + } + } +} + +const customTooltip = ({ backgroundColor, textColor, size = 'md' }: TooltipProps) => + withStyles(theme => ({ + popper: { + zIndex: 2001, + }, + tooltip: { + backgroundColor: + backgroundColor && theme.palette[backgroundColor] + ? (theme.palette[backgroundColor] as PaletteColor).main + : '#E8E7E6', + boxShadow: `1px 2px 10px ${alpha('#28363D', 0.18)}`, + border: getBorderBySize(size), + color: textColor + ? (theme.palette[textColor] as PaletteColor).main + : backgroundColor === 'primary' + ? theme.palette.common.white + : theme.palette.text.primary, + borderRadius: '4px', + fontFamily: theme.typography.fontFamily, + padding: getPaddingBySize(size), + fontSize: getFontInfoBySize(size).fontSize, + lineHeight: getFontInfoBySize(size).lineHeight, + }, + arrow: { + color: backgroundColor ? (theme.palette[backgroundColor] as PaletteColor).main : '#E8E7E6', + border: 'none', + + '&::before': { + boxShadow: `1px 2px 10px ${alpha('#28363D', 0.18)}`, + }, + }, + }))(MUITooltip) + +type Props = { + title: string + children: ReactElement +} & TooltipProps + +export const Tooltip = ({ + title, + backgroundColor, + textColor, + children, + size, + ...rest +}: Props & TooltipPropsMui): ReactElement => { + const StyledTooltip = customTooltip({ + backgroundColor, + textColor, + size, + }) + + return ( + + {children} + + ) +} diff --git a/apps/tx-builder/src/components/buttons/ButtonLink/index.tsx b/apps/tx-builder/src/components/buttons/ButtonLink/index.tsx new file mode 100644 index 000000000..001379080 --- /dev/null +++ b/apps/tx-builder/src/components/buttons/ButtonLink/index.tsx @@ -0,0 +1,52 @@ +import React from 'react' +import styled from 'styled-components' +import { Icon, IconProps, IconType } from '../../Icon' +import Text from '../../Text' +import { TypographyProps } from '@material-ui/core' +import { type Theme } from '@material-ui/core/styles' + +export interface Props extends React.ComponentPropsWithoutRef<'button'> { + iconType?: keyof IconType + iconSize?: IconProps['size'] + textSize?: TypographyProps['variant'] + color: keyof Theme['palette'] + children?: React.ReactNode +} + +const StyledButtonLink = styled.button` + background: transparent; + border: none; + text-decoration: none; + cursor: pointer; + color: ${({ theme, color }) => theme.palette[color].main}; + font-family: ${({ theme }) => theme.typography.fontFamily}; + display: flex; + align-items: center; + + :focus { + outline: none; + } +` + +const StyledText = styled(Text)` + margin: 0 4px; +` + +const ButtonLink = ({ + iconType, + iconSize = 'md', + children, + textSize = 'body1', + ...rest +}: Props): React.ReactElement => { + return ( + + {iconType && } + + {children} + + + ) +} + +export default ButtonLink diff --git a/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/copyTextToClipboard.ts b/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/copyTextToClipboard.ts new file mode 100644 index 000000000..a5939018c --- /dev/null +++ b/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/copyTextToClipboard.ts @@ -0,0 +1,24 @@ +const copyTextToClipboard = (text: string): void => { + const listener = (e: ClipboardEvent): void => { + e.preventDefault() + if (e.clipboardData) { + e.clipboardData.setData('text/plain', text) + } + } + + const range = document.createRange() + + const documentSelection = document.getSelection() + if (!documentSelection) { + return + } + + range.selectNodeContents(document.body) + documentSelection.addRange(range) + document.addEventListener('copy', listener) + document.execCommand('copy') + document.removeEventListener('copy', listener) + documentSelection.removeAllRanges() +} + +export default copyTextToClipboard diff --git a/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/index.tsx b/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/index.tsx new file mode 100644 index 000000000..9b0da7662 --- /dev/null +++ b/apps/tx-builder/src/components/buttons/CopyToClipboardBtn/index.tsx @@ -0,0 +1,78 @@ +import React, { useState } from 'react' +import styled from 'styled-components' + +import copyTextToClipboard from './copyTextToClipboard' +import { Icon } from '../../Icon' + +const StyledButton = styled.button` + background: none; + color: inherit; + border: none; + padding: 0; + font: inherit; + cursor: pointer; + border-radius: 50%; + transition: background-color 0.2s ease-in-out; + outline-color: transparent; + height: 24px; + width: 24px; + display: flex; + justify-content: center; + align-items: center; + :hover { + background-color: ${({ theme }) => theme.palette.divider}; + } +` + +type Props = { + textToCopy: string + className?: string + iconType?: Parameters[0]['type'] + tooltip?: string + tooltipAfterCopy?: string +} + +const CopyToClipboardBtn = ({ + className, + textToCopy, + iconType = 'copy', + tooltip = 'Copy to clipboard', +}: Props): React.ReactElement => { + const [clicked, setClicked] = useState(false) + + const copy = () => { + copyTextToClipboard(textToCopy) + setClicked(true) + } + + const onButtonClick = (event: React.MouseEvent): void => { + event.stopPropagation() + copy() + } + + const onKeyDown = (event: React.KeyboardEvent): void => { + // prevents event from bubbling when `Enter` is pressed + if (event.keyCode === 13) { + event.stopPropagation() + } + copy() + } + + const onButtonBlur = (): void => { + setTimeout((): void => setClicked(false), 300) + } + + return ( + + + + ) +} + +export default CopyToClipboardBtn diff --git a/apps/tx-builder/src/components/buttons/ExplorerButton/index.tsx b/apps/tx-builder/src/components/buttons/ExplorerButton/index.tsx new file mode 100644 index 000000000..f05c81833 --- /dev/null +++ b/apps/tx-builder/src/components/buttons/ExplorerButton/index.tsx @@ -0,0 +1,59 @@ +import React from 'react' +import styled from 'styled-components' +import { Icon } from '../../Icon' +import { ExplorerInfo } from '../../ETHHashInfo' + +const StyledLink = styled.a` + background: none; + color: inherit; + border: none; + padding: 0; + font: inherit; + cursor: pointer; + border-radius: 50%; + transition: background-color 0.2s ease-in-out; + outline-color: transparent; + height: 24px; + width: 24px; + display: flex; + justify-content: center; + align-items: center; + :hover { + background-color: #f0efee; + } +` + +type Props = { + className?: string + explorerUrl: ExplorerInfo +} + +const ExplorerButton = ({ className, explorerUrl }: Props): React.ReactElement => { + const { url, alt } = explorerUrl() + const onClick = (event: React.MouseEvent): void => { + event.stopPropagation() + } + + const onKeyDown = (event: React.KeyboardEvent): void => { + // prevents event from bubbling when `Enter` is pressed + if (event.keyCode === 13) { + event.stopPropagation() + } + } + + return ( + + + + ) +} + +export default ExplorerButton diff --git a/apps/tx-builder/src/components/buttons/Identicon/index.tsx b/apps/tx-builder/src/components/buttons/Identicon/index.tsx new file mode 100644 index 000000000..5ddaac4b2 --- /dev/null +++ b/apps/tx-builder/src/components/buttons/Identicon/index.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' + +import makeBlockie from 'ethereum-blockies-base64' +import styled from 'styled-components' + +export const identiconSizes = { + xs: '10px', + sm: '16px', + md: '32px', + lg: '40px', + xl: '48px', + xxl: '60px', +} + +type Props = { + address: string + size: keyof typeof identiconSizes +} + +const StyledImg = styled.img<{ size: keyof typeof identiconSizes }>` + height: ${({ size }) => identiconSizes[size]}; + width: ${({ size }) => identiconSizes[size]}; + border-radius: 50%; +` + +const Identicon = ({ size = 'md', address, ...rest }: Props): React.ReactElement => { + const iconSrc = React.useMemo(() => makeBlockie(address), [address]) + + return +} + +export default Identicon diff --git a/apps/tx-builder/src/components/forms/fields/AddressInput.tsx b/apps/tx-builder/src/components/forms/fields/AddressInput.tsx new file mode 100644 index 000000000..102c57016 --- /dev/null +++ b/apps/tx-builder/src/components/forms/fields/AddressInput.tsx @@ -0,0 +1,208 @@ +import React, { ReactElement, useState, ChangeEvent, useEffect, useCallback, useRef } from 'react' +import InputAdornment from '@material-ui/core/InputAdornment' +import CircularProgress from '@material-ui/core/CircularProgress' + +import { + addNetworkPrefix, + checksumAddress, + getAddressWithoutNetworkPrefix, + getNetworkPrefix, + isChecksumAddress, + isValidAddress, + isValidEnsName, +} from '../../../utils/address' +import TextFieldInput, { TextFieldInputProps } from './TextFieldInput' +import useThrottle from '../../../hooks/useThrottle' + +type AddressInputProps = { + name: string + address: string + networkPrefix?: string + showNetworkPrefix?: boolean + defaultValue?: string + disabled?: boolean + onChangeAddress: (address: string) => void + getAddressFromDomain?: (name: string) => Promise + customENSThrottleDelay?: number + showLoadingSpinner?: boolean +} & TextFieldInputProps + +function AddressInput({ + name, + address, + networkPrefix, + showNetworkPrefix = true, + disabled, + onChangeAddress, + getAddressFromDomain, + customENSThrottleDelay, + showLoadingSpinner, + InputProps, + inputProps, + hiddenLabel = false, + ...rest +}: AddressInputProps): ReactElement { + const [isLoadingENSResolution, setIsLoadingENSResolution] = useState(false) + const defaultInputValue = addPrefix(address, networkPrefix, showNetworkPrefix) + const inputRef = useRef({ value: defaultInputValue }) + const throttle = useThrottle() + + // we checksum & include the network prefix in the input if showNetworkPrefix is set to true + const updateInputValue = useCallback( + (value = '') => { + if (inputRef.current) { + const checksumAddress = checksumValidAddress(value) + inputRef.current.value = addPrefix(checksumAddress, networkPrefix, showNetworkPrefix) + } + }, + [networkPrefix, showNetworkPrefix], + ) + + const resolveDomainName = useCallback(async () => { + const isEnsName = isValidEnsName(address) + + if (isEnsName && getAddressFromDomain) { + try { + setIsLoadingENSResolution(true) + const resolvedAddress = await getAddressFromDomain(address) + onChangeAddress(checksumValidAddress(resolvedAddress)) + // we update the input value + updateInputValue(resolvedAddress) + } catch (e) { + onChangeAddress(address) + } finally { + setIsLoadingENSResolution(false) + } + } + }, [address, getAddressFromDomain, onChangeAddress, updateInputValue]) + + // ENS name resolution + useEffect(() => { + if (getAddressFromDomain) { + throttle(resolveDomainName, customENSThrottleDelay) + } + }, [getAddressFromDomain, resolveDomainName, customENSThrottleDelay, throttle]) + + // if address changes from outside (Like Loaded from a QR code) we update the input value + useEffect(() => { + const inputValue = inputRef.current?.value + const inputWithoutPrefix = getAddressWithoutNetworkPrefix(inputValue) + const addressWithoutPrefix = getAddressWithoutNetworkPrefix(address) + const inputPrefix = getNetworkPrefix(inputValue) + const addressPrefix = getNetworkPrefix(address) + + const isNewAddressLoaded = inputWithoutPrefix !== addressWithoutPrefix + const isNewPrefixLoaded = addressPrefix && inputPrefix !== addressPrefix + + // we check if we load a new address (both prefixed and unprefixed cases) + if (isNewAddressLoaded || isNewPrefixLoaded) { + // we update the input value + updateInputValue(address) + } + }, [address, updateInputValue]) + + // we trim, checksum & remove valid network prefix when a valid address is typed by the user + const updateAddressState = useCallback( + value => { + const inputValue = value.trim() + + const inputPrefix = getNetworkPrefix(inputValue) + const inputWithoutPrefix = getAddressWithoutNetworkPrefix(inputValue) + + // if the valid network prefix is present, we remove it from the address state + const isValidPrefix = networkPrefix === inputPrefix + const checksumAddress = checksumValidAddress(isValidPrefix ? inputWithoutPrefix : inputValue) + + onChangeAddress(checksumAddress) + }, + [networkPrefix, onChangeAddress], + ) + + // when user switch the network we update the address state + useEffect(() => { + // Because the `address` is going to change after we call `updateAddressState` + // To avoid calling `updateAddressState` twice, we check the value and the current address + const inputValue = inputRef.current?.value + if (inputValue !== address) { + updateAddressState(inputRef.current?.value) + } + }, [networkPrefix, address, updateAddressState]) + + // when user types we update the address state + function onChange(e: ChangeEvent) { + updateAddressState(e.target.value) + } + + const isLoading = isLoadingENSResolution || showLoadingSpinner + + const [shrink, setshrink] = useState(!!defaultInputValue) + + useEffect(() => { + setshrink(!!inputRef.current?.value) + }, [inputRef.current.value]) + + return ( + : InputProps?.endAdornment, + }} + inputProps={{ + ...inputProps, + ref: inputRef, + }} + InputLabelProps={{ + ...rest.InputLabelProps, + shrink: shrink || hiddenLabel || undefined, + }} + spellCheck={false} + {...rest} + /> + ) +} + +export default AddressInput + +function LoaderSpinnerAdornment() { + return ( + + + + ) +} + +// we only checksum valid addresses +function checksumValidAddress(address: string) { + if (isValidAddress(address) && !isChecksumAddress(address)) { + return checksumAddress(address) + } + + return address +} + +// we try to add the network prefix if its not present +function addPrefix( + address: string, + networkPrefix: string | undefined, + showNetworkPrefix = false, +): string { + if (!address) { + return '' + } + + if (showNetworkPrefix && networkPrefix) { + const hasPrefix = !!getNetworkPrefix(address) + + // if the address has not prefix we add it by default + if (!hasPrefix) { + return addNetworkPrefix(address, networkPrefix) + } + } + + return address +} diff --git a/apps/tx-builder/src/components/forms/fields/TextFieldInput.tsx b/apps/tx-builder/src/components/forms/fields/TextFieldInput.tsx new file mode 100644 index 000000000..1f00e40fb --- /dev/null +++ b/apps/tx-builder/src/components/forms/fields/TextFieldInput.tsx @@ -0,0 +1,57 @@ +import React, { ReactElement } from 'react' +import TextFieldMui, { TextFieldProps } from '@material-ui/core/TextField' +import styled from 'styled-components' +import { errorStyles, inputLabelStyles, inputStyles } from './styles' + +export type TextFieldInputProps = { + id?: string + name: string + label: string + error?: string + helperText?: string | undefined + hiddenLabel?: boolean | undefined + showErrorsInTheLabel?: boolean | undefined +} & Omit + +function TextFieldInput({ + id, + name, + label, + error = '', + helperText, + value, + hiddenLabel, + showErrorsInTheLabel, + ...rest +}: TextFieldInputProps): ReactElement { + const hasError = !!error + + return ( + + ) +} + +const TextField = styled((props: TextFieldProps) => )` + && { + ${inputLabelStyles} + ${inputStyles} + ${errorStyles} + } +` + +export default TextFieldInput diff --git a/apps/tx-builder/src/components/forms/fields/styles.ts b/apps/tx-builder/src/components/forms/fields/styles.ts new file mode 100644 index 000000000..3581130b6 --- /dev/null +++ b/apps/tx-builder/src/components/forms/fields/styles.ts @@ -0,0 +1,118 @@ +import { TextFieldProps } from '@material-ui/core' +import { css } from 'styled-components' + +export const inputLabelStyles = css` + &:hover { + .MuiInputLabel-root { + &.MuiInputLabel-shrink:not(.Mui-focused):not(.Mui-disabled) { + color: ${({ theme }) => theme.palette.primary.main}; + &.Mui-error { + color: ${({ theme }) => theme.palette.error.main}; + } + } + } + } + + .MuiInputLabel-root { + font-family: ${({ theme }) => theme.typography.fontFamily}; + color: ${({ theme }) => theme.palette.text.secondary}; + font-weight: 300; + font-size: 16px; + + &.MuiInputLabel-shrink { + color: #162d45; + + &.Mui-error { + color: ${({ theme }) => theme.palette.error.main}; + } + } + &.Mui-disabled { + color: #dadada; + } + + /* Hide Label */ + ${({ hiddenLabel }) => + hiddenLabel + ? `border: 0; + border: 1px solid red; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px;` + : ''} + } +` + +export const inputStyles = css` + .MuiOutlinedInput-input:-webkit-autofill { + -webkit-text-fill-color: ${({ theme }) => theme.palette.text.primary}; + } + + .MuiOutlinedInput-root { + font-family: ${({ theme }) => theme.typography.fontFamily}; + color: ${({ theme }) => theme.palette.text.primary}; + /* Input */ + .MuiOutlinedInput-input { + &::placeholder, + &.Mui-disabled { + cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'auto')}; + color: #b2bbc0; + } + } + + /* fieldset */ + .MuiOutlinedInput-notchedOutline { + ${({ hiddenLabel }) => (hiddenLabel ? 'top: 0' : '')}; + transition: border-color 0.2s ease-in-out; + border: 1px solid ${({ theme, value }) => (value ? theme.palette.border.main : '#DADADA')}; + border-radius: 6px; + legend { + display: ${({ hiddenLabel }) => (hiddenLabel ? 'none' : 'block')}; + } + } + + &:hover { + .MuiOutlinedInput-notchedOutline { + border-color: ${({ theme }) => theme.palette.primary.main}; + } + } + + &.Mui-focused { + .MuiOutlinedInput-notchedOutline { + border-color: #566976; + } + &.Mui-error { + .MuiOutlinedInput-notchedOutline { + border-color: ${({ theme }) => theme.palette.error.main}; + } + } + } + &.Mui-disabled { + .MuiOutlinedInput-notchedOutline { + border-color: #dadada; + } + } + } + .MuiFormLabel-filled + + .MuiOutlinedInput-root:not(:hover):not(.Mui-disabled) + .MuiOutlinedInput-notchedOutline { + border-color: ${({ theme, error }) => (error ? theme.palette.error.main : '#566976')}; + } +` + +export const errorStyles = css` + .Mui-error { + &:hover, + .Mui-focused { + .MuiOutlinedInput-notchedOutline { + border-color: ${({ theme }) => theme.palette.error.main}; + } + } + .MuiOutlinedInput-notchedOutline { + border-color: ${({ theme }) => theme.palette.error.main}; + } + } +` diff --git a/apps/tx-builder/src/hooks/useDebounce.ts b/apps/tx-builder/src/hooks/useDebounce.ts new file mode 100644 index 000000000..18d25366e --- /dev/null +++ b/apps/tx-builder/src/hooks/useDebounce.ts @@ -0,0 +1,14 @@ +import { useEffect, useState } from 'react' + +const useDebounce = (value: T, delay: number): T => { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay) + return () => clearTimeout(timer) + }, [value, delay]) + + return debouncedValue +} + +export default useDebounce diff --git a/apps/tx-builder/src/hooks/useThrottle.ts b/apps/tx-builder/src/hooks/useThrottle.ts new file mode 100644 index 000000000..b5c91f7d8 --- /dev/null +++ b/apps/tx-builder/src/hooks/useThrottle.ts @@ -0,0 +1,26 @@ +import { useRef, useCallback } from 'react' + +const DEFAULT_DELAY = 650 + +type ThrottleType = (callback: Function, delay?: number) => void + +const useThrottle: () => ThrottleType = () => { + const timerRefId = useRef | undefined>() + + const throttle = useCallback((callback, delay = DEFAULT_DELAY) => { + // If setTimeout is already scheduled, clearTimeout + if (timerRefId.current) { + clearTimeout(timerRefId.current) + } + + // Schedule the exec after a delay + timerRefId.current = setTimeout(function () { + timerRefId.current = undefined + return callback() + }, delay) + }, []) + + return throttle +} + +export default useThrottle diff --git a/apps/tx-builder/src/theme/SafeThemeProvider.tsx b/apps/tx-builder/src/theme/SafeThemeProvider.tsx new file mode 100644 index 000000000..784f3a3fb --- /dev/null +++ b/apps/tx-builder/src/theme/SafeThemeProvider.tsx @@ -0,0 +1,17 @@ +import { useMemo, type FC } from 'react' +import { type PaletteMode, type Theme } from '@mui/material' +import { ThemeProvider } from '@material-ui/core' +import createSafeTheme from './safeTheme' + +type SafeThemeProviderProps = { + children: (theme: Theme) => React.ReactNode + mode: PaletteMode +} + +const SafeThemeProvider: FC = ({ children, mode }) => { + const theme = useMemo(() => createSafeTheme(mode), [mode]) + + return {children(theme)} +} + +export default SafeThemeProvider diff --git a/apps/tx-builder/src/theme/lightPalette.ts b/apps/tx-builder/src/theme/lightPalette.ts new file mode 100644 index 000000000..a47daca3f --- /dev/null +++ b/apps/tx-builder/src/theme/lightPalette.ts @@ -0,0 +1,65 @@ +const lightPalette = { + text: { + primary: '#121312', + secondary: '#A1A3A7', + disabled: '#DDDEE0', + }, + primary: { + dark: '#3c3c3c', + main: '#121312', + light: '#636669', + }, + secondary: { + dark: '#0FDA6D', + main: '#12FF80', + light: '#B0FFC9', + background: '#EFFFF4', + }, + border: { + main: '#A1A3A7', + light: '#DCDEE0', + background: '#F4F4F4', + }, + error: { + dark: '#AC2C3B', + main: '#FF5F72', + light: '#FFB4BD', + background: '#FFE6EA', + }, + success: { + dark: '#028D4C', + main: '#00B460', + light: '#72F5B8', + background: '#EFFAF1', + }, + info: { + dark: '#52BFDC', + main: '#5FDDFF', + light: '#B7F0FF', + background: '#EFFCFF', + }, + warning: { + dark: '#C04C32', + main: '#FF8061', + light: '#FFBC9F', + background: '#FFF1E0', + }, + background: { + default: '#F4F4F4', + main: '#F4F4F4', + paper: '#FFFFFF', + light: '#EFFFF4', + }, + backdrop: { + main: '#636669', + }, + logo: { + main: '#121312', + background: '#EEEFF0', + }, + static: { + main: '#121312', + }, +} + +export default lightPalette diff --git a/apps/tx-builder/src/theme/safeTheme.ts b/apps/tx-builder/src/theme/safeTheme.ts new file mode 100644 index 000000000..97f356d41 --- /dev/null +++ b/apps/tx-builder/src/theme/safeTheme.ts @@ -0,0 +1,520 @@ +import type { Theme, PaletteMode } from '@mui/material' +import { alpha } from '@mui/material' +import type { Shadows } from '@mui/material/styles' +import { createTheme } from '@mui/material/styles' + +import palette from './lightPalette' +import typography from './typography' + +export const base = 8 + +declare module '@mui/material/styles' { + // Custom color palettes + export interface Palette { + border: Palette['primary'] + logo: Palette['primary'] + backdrop: Palette['primary'] + static: Palette['primary'] + } + + export interface PaletteOptions { + border: PaletteOptions['primary'] + logo: PaletteOptions['primary'] + backdrop: PaletteOptions['primary'] + static: PaletteOptions['primary'] + } + + export interface TypeBackground { + main: string + light: string + } + + // Custom color properties + export interface PaletteColor { + background?: string + } + + export interface SimplePaletteColorOptions { + background?: string + } +} + +declare module '@mui/material/SvgIcon' { + export interface SvgIconPropsColorOverrides { + border: unknown + } +} + +declare module '@mui/material/Button' { + export interface ButtonPropsSizeOverrides { + stretched: true + } + + export interface ButtonPropsColorOverrides { + background: true + } + + export interface ButtonPropsVariantOverrides { + danger: true + } +} + +declare module '@mui/material/IconButton' { + export interface IconButtonPropsColorOverrides { + border: true + } +} + +const createSafeTheme = (mode: PaletteMode): Theme => { + const isDarkMode = mode === 'dark' + const shadowColor = palette.primary.light + + return createTheme({ + palette: { + mode: isDarkMode ? 'dark' : 'light', + ...palette, + }, + spacing: base, + shape: { + borderRadius: 6, + }, + shadows: [ + 'none', + isDarkMode + ? `0 0 2px ${shadowColor}` + : `0 1px 4px ${shadowColor}0a, 0 4px 10px ${shadowColor}14`, + isDarkMode + ? `0 0 2px ${shadowColor}` + : `0 1px 4px ${shadowColor}0a, 0 4px 10px ${shadowColor}14`, + isDarkMode + ? `0 0 2px ${shadowColor}` + : `0 2px 20px ${shadowColor}0a, 0 8px 32px ${shadowColor}14`, + isDarkMode + ? `0 0 2px ${shadowColor}` + : `0 8px 32px ${shadowColor}0a, 0 24px 60px ${shadowColor}14`, + ...Array(20).fill('none'), + ] as Shadows, + typography, + components: { + MuiTableCell: { + styleOverrides: { + head: ({ theme }) => ({ + ...theme.typography.body1, + color: theme.palette.primary.light, + }), + }, + }, + MuiButton: { + variants: [ + { + props: { size: 'stretched' }, + style: { + padding: '12px 48px', + }, + }, + { + props: { variant: 'danger' }, + style: ({ theme }) => ({ + backgroundColor: theme.palette.error.background, + color: theme.palette.error.main, + '&:hover': { + color: theme.palette.error.dark, + backgroundColor: theme.palette.error.light, + }, + }), + }, + ], + styleOverrides: { + sizeSmall: { + fontSize: '14px', + padding: '8px 24px', + }, + sizeMedium: { + fontSize: '16px', + padding: '12px 24px', + }, + root: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + fontWeight: 'bold', + lineHeight: 1.25, + borderColor: theme.palette.primary.main, + textTransform: 'none', + '&:hover': { + boxShadow: 'none', + }, + }), + outlined: { + border: '2px solid', + '&:hover': { + border: '2px solid', + }, + }, + sizeLarge: { fontSize: '16px' }, + }, + }, + MuiAccordion: { + variants: [ + { + props: { variant: 'elevation' }, + style: ({ theme }) => ({ + border: 'none', + boxShadow: '0', + '&:not(:last-of-type)': { + borderRadius: '0 !important', + borderBottom: `1px solid ${theme.palette.border.light}`, + }, + '&:last-of-type': { + borderBottomLeftRadius: '8px', + }, + }), + }, + ], + styleOverrides: { + root: ({ theme }) => ({ + transition: 'background 0.2s, border 0.2s', + borderRadius: theme.shape.borderRadius, + border: `1px solid ${theme.palette.border.light}`, + overflow: 'hidden', + + '&::before': { + content: 'none', + }, + + '&:hover': { + borderColor: theme.palette.secondary.light, + }, + + '&:hover > .MuiAccordionSummary-root': { + background: theme.palette.background.light, + }, + + '&.Mui-expanded': { + margin: 0, + borderColor: theme.palette.secondary.light, + }, + + '&.Mui-expanded > .MuiAccordionSummary-root': { + background: theme.palette.background.light, + }, + }), + }, + }, + MuiAccordionSummary: { + styleOverrides: { + root: { + '&.Mui-expanded': { + minHeight: '48px', + }, + }, + content: { + '&.Mui-expanded': { + margin: '12px 0', + }, + }, + }, + }, + MuiAccordionDetails: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(2), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + boxSizing: 'border-box', + border: '2px solid transparent', + boxShadow: 'none', + }), + }, + }, + MuiDialog: { + defaultProps: { + fullWidth: true, + }, + }, + MuiDialogContent: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(3), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: theme.palette.border.light, + }), + }, + }, + MuiPaper: { + defaultProps: { + elevation: 0, + }, + styleOverrides: { + outlined: ({ theme }) => ({ + borderWidth: 2, + borderColor: theme.palette.border.light, + }), + root: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + backgroundImage: 'none', + }), + }, + }, + MuiPopover: { + defaultProps: { + elevation: 2, + }, + styleOverrides: { + paper: { + overflow: 'visible', + }, + }, + }, + MuiIconButton: { + styleOverrides: { + sizeSmall: { + padding: '4px', + }, + }, + }, + MuiToggleButton: { + styleOverrides: { + root: { + textTransform: 'none', + }, + }, + }, + MuiChip: { + styleOverrides: { + colorSuccess: ({ theme }) => ({ + backgroundColor: theme.palette.secondary.light, + height: '24px', + }), + }, + }, + MuiAlert: { + styleOverrides: { + standardError: ({ theme }) => ({ + '& .MuiAlert-icon': { + color: theme.palette.error.main, + }, + '&.MuiPaper-root': { + backgroundColor: theme.palette.error.background, + }, + border: `1px solid ${theme.palette.error.main}`, + }), + standardInfo: ({ theme }) => ({ + '& .MuiAlert-icon': { + color: theme.palette.info.main, + }, + '&.MuiPaper-root': { + backgroundColor: theme.palette.info.background, + }, + border: `1px solid ${theme.palette.info.main}`, + }), + standardSuccess: ({ theme }) => ({ + '& .MuiAlert-icon': { + color: theme.palette.success.main, + }, + '&.MuiPaper-root': { + backgroundColor: theme.palette.success.background, + }, + border: `1px solid ${theme.palette.success.main}`, + }), + standardWarning: ({ theme }) => ({ + '& .MuiAlert-icon': { + color: theme.palette.warning.main, + }, + '&.MuiPaper-root': { + backgroundColor: theme.palette.warning.background, + }, + border: `1px solid ${theme.palette.warning.main}`, + }), + root: ({ theme }) => ({ + color: theme.palette.text.primary, + padding: '12px 16px', + }), + }, + }, + MuiTableHead: { + styleOverrides: { + root: ({ theme }) => ({ + '& .MuiTableCell-root': { + borderBottom: `1px solid ${theme.palette.border.light}`, + }, + + [theme.breakpoints.down('sm')]: { + '& .MuiTableCell-root:first-of-type': { + paddingRight: theme.spacing(1), + }, + + '& .MuiTableCell-root:not(:first-of-type):not(:last-of-type)': { + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), + }, + + '& .MuiTableCell-root:last-of-type': { + paddingLeft: theme.spacing(1), + }, + }, + }), + }, + }, + MuiTableBody: { + styleOverrides: { + root: ({ theme }) => ({ + '& .MuiTableCell-root': { + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(1), + borderBottom: 'none', + }, + + [theme.breakpoints.down('sm')]: { + '& .MuiTableCell-root:first-of-type': { + paddingRight: theme.spacing(1), + }, + + '& .MuiTableCell-root:not(:first-of-type):not(:last-of-type)': { + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), + }, + + '& .MuiTableCell-root:last-of-type': { + paddingLeft: theme.spacing(1), + }, + }, + + '& .MuiTableRow-root': { + transition: 'background-color 0.2s', + '&:not(:last-of-type)': { + borderBottom: `1px solid ${theme.palette.border.light}`, + }, + }, + + '& .MuiTableRow-root:hover': { + backgroundColor: theme.palette.background.light, + }, + '& .MuiTableRow-root.Mui-selected': { + backgroundColor: theme.palette.background.light, + }, + }), + }, + }, + MuiCheckbox: { + styleOverrides: { + root: ({ theme }) => ({ + color: theme.palette.primary.main, + }), + }, + }, + MuiOutlinedInput: { + styleOverrides: { + notchedOutline: ({ theme }) => ({ + borderColor: theme.palette.border.main, + }), + root: ({ theme }) => ({ + borderColor: theme.palette.border.main, + }), + }, + }, + MuiSvgIcon: { + styleOverrides: { + fontSizeSmall: { + width: '1rem', + height: '1rem', + }, + }, + }, + MuiFilledInput: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 4, + backgroundColor: theme.palette.background.paper, + border: '1px solid transparent', + transition: 'border-color 0.2s', + + '&:hover, &:focus, &.Mui-focused': { + backgroundColor: theme.palette.background.paper, + borderColor: theme.palette.primary.main, + }, + }), + }, + }, + MuiSelect: { + defaultProps: { + MenuProps: { + sx: { + '& .MuiPaper-root': { + overflow: 'auto', + }, + }, + }, + }, + }, + MuiTooltip: { + styleOverrides: { + tooltip: ({ theme }) => ({ + ...theme.typography.body2, + color: theme.palette.background.main, + backgroundColor: theme.palette.text.primary, + '& .MuiLink-root': { + color: isDarkMode ? theme.palette.background.main : theme.palette.secondary.main, + textDecorationColor: isDarkMode + ? theme.palette.background.main + : theme.palette.secondary.main, + }, + '& .MuiLink-root:hover': { + color: isDarkMode ? theme.palette.text.secondary : theme.palette.secondary.light, + }, + }), + arrow: ({ theme }) => ({ + color: theme.palette.text.primary, + }), + }, + }, + MuiBackdrop: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: alpha(theme.palette.backdrop.main, 0.75), + }), + }, + }, + MuiSwitch: { + defaultProps: { + color: isDarkMode ? undefined : 'success', + }, + styleOverrides: { + thumb: () => ({ + boxShadow: + '0px 2px 6px -1px rgba(0, 0, 0, 0.2), 0px 1px 4px rgba(0, 0, 0, 0.14), 0px 1px 4px rgba(0, 0, 0, 0.14)', + }), + }, + }, + MuiLink: { + styleOverrides: { + root: ({ theme }) => ({ + fontWeight: 700, + '&:hover': { + color: theme.palette.primary.light, + }, + }), + }, + }, + MuiLinearProgress: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.border.light, + }), + }, + }, + }, + }) +} + +export const defaultTheme = createSafeTheme('light') + +export default createSafeTheme diff --git a/apps/tx-builder/src/theme/typography.ts b/apps/tx-builder/src/theme/typography.ts new file mode 100644 index 000000000..3058ccd9d --- /dev/null +++ b/apps/tx-builder/src/theme/typography.ts @@ -0,0 +1,50 @@ +import type { TypographyOptions } from '@mui/material/styles/createTypography' + +const safeFontFamily = 'DM Sans, sans-serif' + +const typography: TypographyOptions = { + fontFamily: safeFontFamily, + h1: { + fontSize: '32px', + lineHeight: '36px', + fontWeight: 700, + }, + h2: { + fontSize: '27px', + lineHeight: '34px', + fontWeight: 700, + }, + h3: { + fontSize: '24px', + lineHeight: '30px', + }, + h4: { + fontSize: '20px', + lineHeight: '26px', + }, + h5: { + fontSize: '16px', + fontWeight: 700, + }, + body1: { + fontSize: '16px', + lineHeight: '22px', + }, + body2: { + fontSize: '14px', + lineHeight: '20px', + }, + caption: { + fontSize: '12px', + lineHeight: '16px', + letterSpacing: '0.4px', + }, + overline: { + fontSize: '11px', + lineHeight: '14px', + textTransform: 'uppercase', + letterSpacing: '1px', + }, +} + +export default typography diff --git a/apps/tx-builder/src/utils/address.ts b/apps/tx-builder/src/utils/address.ts new file mode 100644 index 000000000..d78743c2b --- /dev/null +++ b/apps/tx-builder/src/utils/address.ts @@ -0,0 +1,59 @@ +import { checkAddressChecksum, toChecksumAddress, isAddress, isHexStrict } from 'web3-utils' + +const getAddressWithoutNetworkPrefix = (address = ''): string => { + const hasPrefix = address.includes(':') + + if (!hasPrefix) { + return address + } + + const [, ...addressWithoutNetworkPrefix] = address.split(':') + + return addressWithoutNetworkPrefix.join('') +} + +const getNetworkPrefix = (address = ''): string => { + const splitAddress = address.split(':') + const hasPrefixDefined = splitAddress.length > 1 + const [prefix] = splitAddress + return hasPrefixDefined ? prefix : '' +} + +const addNetworkPrefix = (address: string, prefix: string | undefined): string => { + return !!prefix ? `${prefix}:${address}` : address +} + +const checksumAddress = (address: string): string => toChecksumAddress(address) + +const isChecksumAddress = (address?: string): boolean => { + if (address) { + return checkAddressChecksum(address) + } + + return false +} + +const isValidAddress = (address?: string): boolean => { + if (address) { + // `isAddress` do not require the string to start with `0x` + // `isHexStrict` ensures the address to start with `0x` aside from being a valid hex string + return isHexStrict(address) && isAddress(address) + } + + return false +} + +// Based on https://docs.ens.domains/dapp-developer-guide/resolving-names +// [...] a correct integration of ENS treats any dot-separated name as a potential ENS name [...] +const validENSRegex = new RegExp(/[^[\]]+\.[^[\]]/) +const isValidEnsName = (name: string): boolean => validENSRegex.test(name) + +export { + getAddressWithoutNetworkPrefix, + getNetworkPrefix, + addNetworkPrefix, + checksumAddress, + isChecksumAddress, + isValidAddress, + isValidEnsName, +} diff --git a/apps/tx-builder/src/utils/strings.ts b/apps/tx-builder/src/utils/strings.ts new file mode 100644 index 000000000..2cebc15e3 --- /dev/null +++ b/apps/tx-builder/src/utils/strings.ts @@ -0,0 +1,25 @@ +export const textShortener = ( + text: string, + charsStart: number, + charsEnd: number, + separator = '...', +): string => { + const amountOfCharsToKeep = charsEnd + charsStart + + if (amountOfCharsToKeep >= text.length || !amountOfCharsToKeep) { + // no need to shorten + return text + } + + const r = new RegExp(`^(.{${charsStart}}).+(.{${charsEnd}})$`) + const matchResult = r.exec(text) + + if (!matchResult) { + // if for any reason the exec returns null, the text remains untouched + return text + } + + const [, textStart, textEnd] = matchResult + + return `${textStart}${separator}${textEnd}` +} From 6c43cbd2ff69f32f1a3776161ec320d7ddd0fa80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Fri, 4 Oct 2024 11:21:19 +0200 Subject: [PATCH 4/5] feat(tx-builder-theme): update tx-builder theme --- apps/tx-builder/src/assets/add-new-batch.svg | 2 +- .../src/components/CreateNewBatchCard.tsx | 32 +++-- .../src/components/FixedIcon/images/plus.tsx | 17 ++- apps/tx-builder/src/components/Header.tsx | 58 +++++--- .../src/components/Icon/images/alert.tsx | 6 +- .../src/components/Icon/images/bookmark.tsx | 40 +++--- .../components/Icon/images/bookmarkFilled.tsx | 6 +- .../src/components/Icon/images/check.tsx | 6 +- .../src/components/Icon/images/code.tsx | 6 +- .../src/components/Icon/images/copy.tsx | 6 +- .../src/components/Icon/images/cross.tsx | 4 +- .../src/components/Icon/images/delete.tsx | 70 ++++++--- .../src/components/Icon/images/edit.tsx | 36 +++-- .../components/Icon/images/externalLink.tsx | 6 +- .../src/components/Icon/images/import.tsx | 42 +++--- .../src/components/Icon/images/info.tsx | 6 +- .../src/components/Icon/images/termsOfUse.tsx | 36 +++-- apps/tx-builder/src/components/Icon/index.tsx | 135 +----------------- apps/tx-builder/src/components/QuickTip.tsx | 8 +- .../src/components/ShowMoreText.tsx | 2 +- .../components/TransactionBatchListItem.tsx | 93 ++++++------ .../src/components/TransactionDetails.tsx | 80 ++++++----- .../src/components/TransactionsBatchList.tsx | 62 +++----- .../forms/AddNewTransactionForm.tsx | 24 +++- .../forms/fields/AddressContractField.tsx | 2 +- .../src/components/forms/fields/JsonField.tsx | 25 ++-- .../forms/fields/SelectContractField.tsx | 2 +- .../forms/fields/TextContractField.tsx | 3 +- .../forms/fields/TextareaContractField.tsx | 2 +- .../modals/DeleteBatchFromLibrary.tsx | 36 +++-- .../components/modals/DeleteBatchModal.tsx | 19 ++- .../modals/DeleteTransactionModal.tsx | 17 +-- .../modals/EditTransactionModal.tsx | 7 +- .../modals/ImplementationABIDialog.tsx | 18 ++- .../src/components/modals/SaveBatchModal.tsx | 7 +- .../modals/SuccessBatchCreationModal.tsx | 30 ++-- .../modals/WrongChainBatchModal.tsx | 9 +- apps/tx-builder/src/global.ts | 19 ++- apps/tx-builder/src/index.tsx | 26 ++-- .../src/pages/CreateTransactions.tsx | 8 +- apps/tx-builder/src/pages/Dashboard.tsx | 44 +++--- .../src/pages/EditTransactionLibrary.tsx | 3 +- .../tx-builder/src/pages/ReviewAndConfirm.tsx | 84 +++++------ .../src/pages/SaveTransactionLibrary.tsx | 3 +- .../src/pages/TransactionLibrary.tsx | 116 ++++++--------- apps/tx-builder/src/test-utils.tsx | 20 +-- yarn.lock | 5 + 47 files changed, 601 insertions(+), 687 deletions(-) diff --git a/apps/tx-builder/src/assets/add-new-batch.svg b/apps/tx-builder/src/assets/add-new-batch.svg index 5303c416d..274ee0969 100644 --- a/apps/tx-builder/src/assets/add-new-batch.svg +++ b/apps/tx-builder/src/assets/add-new-batch.svg @@ -2,7 +2,7 @@ - + diff --git a/apps/tx-builder/src/components/CreateNewBatchCard.tsx b/apps/tx-builder/src/components/CreateNewBatchCard.tsx index 3ffe0e30e..883069928 100644 --- a/apps/tx-builder/src/components/CreateNewBatchCard.tsx +++ b/apps/tx-builder/src/components/CreateNewBatchCard.tsx @@ -1,5 +1,4 @@ import { useRef } from 'react' -import { ButtonLink, Icon, Text } from '@gnosis.pm/safe-react-components' import { alpha } from '@material-ui/core' import Hidden from '@material-ui/core/Hidden' import styled from 'styled-components' @@ -8,6 +7,9 @@ import { useTheme } from '@material-ui/core/styles' import { ReactComponent as CreateNewBatchSVG } from '../assets/add-new-batch.svg' import useDropZone from '../hooks/useDropZone' import { useMediaQuery } from '@material-ui/core' +import { Icon } from './Icon' +import Text from './Text' +import ButtonLink from './buttons/ButtonLink' type CreateNewBatchCardProps = { onFileSelected: (file: File | null) => void @@ -47,14 +49,14 @@ const CreateNewBatchCard = ({ onFileSelected }: CreateNewBatchCardProps) => { error={isAcceptError} > {isAcceptError ? ( - + The uploaded file is not a valid JSON file ) : ( <> - Drag and drop a JSON file or - + Drag and drop a JSON file or + choose a file @@ -85,9 +87,11 @@ const StyledDragAndDropFileContainer = styled.div<{ }>` box-sizing: border-box; max-width: ${({ fullWidth }) => (fullWidth ? '100%' : '420px')}; - border: 2px dashed ${({ theme, error }) => (error ? theme.colors.error : '#008c73')}; + border: 2px dashed + ${({ theme, error }) => (error ? theme.palette.error.main : theme.palette.secondary.dark)}; border-radius: 8px; - background-color: ${({ theme, error }) => (error ? alpha(theme.colors.error, 0.7) : '#eaf7f4')}; + background-color: ${({ theme, error }) => + error ? alpha(theme.palette.error.main, 0.7) : theme.palette.secondary.background}; padding: 24px; margin: 24px auto 0 auto; @@ -104,22 +108,28 @@ const StyledDragAndDropFileContainer = styled.div<{ } return ` - border-color: ${error ? theme.colors.error : '#008c73'}; - background-color: ${error ? alpha(theme.colors.error, 0.7) : '#eaf7f4'}; + border-color: ${error ? theme.palette.error.main : theme.palette.secondary.dark}; + background-color: ${ + error ? alpha(theme.palette.error.main, 0.7) : theme.palette.secondary.background + }; ` }} ` const StyledText = styled(Text)<{ error?: Boolean }>` - margin-left: 4px; - color: ${({ error }) => (error ? '#FFF' : '#566976')}; + && { + margin-left: 4px; + color: ${({ error, theme }) => + error ? theme.palette.common.white : theme.palette.text.secondary}; + } ` const StyledButtonLink = styled(ButtonLink)` + margin-left: 0.3rem; padding: 0; text-decoration: none; && > p { - font-size: 16px; + color: ${({ theme }) => theme.palette.secondary.dark}; } ` diff --git a/apps/tx-builder/src/components/FixedIcon/images/plus.tsx b/apps/tx-builder/src/components/FixedIcon/images/plus.tsx index 408a2bf71..290cfea6e 100644 --- a/apps/tx-builder/src/components/FixedIcon/images/plus.tsx +++ b/apps/tx-builder/src/components/FixedIcon/images/plus.tsx @@ -1,11 +1,16 @@ -import React from 'react' - const icon = ( - + + ) diff --git a/apps/tx-builder/src/components/Header.tsx b/apps/tx-builder/src/components/Header.tsx index e4cb36827..ba727e6d3 100644 --- a/apps/tx-builder/src/components/Header.tsx +++ b/apps/tx-builder/src/components/Header.tsx @@ -1,4 +1,3 @@ -import { FixedIcon, Icon, Text, Title, Tooltip } from '@gnosis.pm/safe-react-components' import { Link, useLocation, useNavigate } from 'react-router-dom' import styled from 'styled-components' @@ -12,6 +11,11 @@ import { import { useTransactionLibrary } from '../store' import ChecksumWarning from './ChecksumWarning' import ErrorAlert from './ErrorAlert' +import { Tooltip } from './Tooltip' +import { Icon } from './Icon' +import FixedIcon from './FixedIcon' +import { Typography } from '@material-ui/core' +import Text from './Text' const HELP_ARTICLE_LINK = 'https://help.safe.global/en/articles/40841-transaction-builder' @@ -51,31 +55,25 @@ const Header = () => { {showTitle ? ( <> {/* Transaction Builder Title */} - Transaction Builder - - + Transaction Builder + + - + ) : ( {/* Go Back link */} - {goBackLabel[previousUrl]} + {goBackLabel[previousUrl]} )} {showLinkToLibrary && ( - {`(${batches.length}) Your transaction library`} + {`(${batches.length}) Your transaction library`} @@ -102,21 +100,35 @@ const HeaderWrapper = styled.header` box-sizing: border-box; ` -const StyledTitle = styled(Title)` - font-size: 20px; - margin: 0 10px 0 0; +const StyledTitle = styled(Typography)` + && { + font-size: 20px; + font-weight: 700; + margin: 0 10px 0 0; + } ` const StyledLink = styled(Link)` display: flex; align-items: center; - color: #000000; + color: ${({ theme }) => theme.palette.common.black}; font-size: 16px; text-decoration: none; + + > span { + padding-top: 3px; + + path { + fill: ${({ theme }) => theme.palette.common.black}; + } + } ` const StyledLeftLinkLabel = styled(Text)` - margin-left: 8px; + && { + margin-left: 8px; + font-weight: 700; + } ` const RigthLinkWrapper = styled.div` @@ -126,5 +138,13 @@ const RigthLinkWrapper = styled.div` ` const StyledRightLinkLabel = styled(Text)` - margin-right: 8px; + && { + font-weight: 700; + margin-right: 8px; + } +` + +const StyledIconLink = styled.a` + display: flex; + align-items: center; ` diff --git a/apps/tx-builder/src/components/Icon/images/alert.tsx b/apps/tx-builder/src/components/Icon/images/alert.tsx index 7bbb9897a..b1618a408 100644 --- a/apps/tx-builder/src/components/Icon/images/alert.tsx +++ b/apps/tx-builder/src/components/Icon/images/alert.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const Alert = { sm: ( @@ -32,3 +30,5 @@ export default { ), } + +export default Alert diff --git a/apps/tx-builder/src/components/Icon/images/bookmark.tsx b/apps/tx-builder/src/components/Icon/images/bookmark.tsx index 528ccf212..6f6cc8e33 100644 --- a/apps/tx-builder/src/components/Icon/images/bookmark.tsx +++ b/apps/tx-builder/src/components/Icon/images/bookmark.tsx @@ -1,30 +1,24 @@ -import React from 'react' - -export default { +const Bookmark = { sm: ( - - - - + + ), md: ( - - - - + + ), } + +export default Bookmark diff --git a/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx b/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx index a8fdec094..c0128163d 100644 --- a/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx +++ b/apps/tx-builder/src/components/Icon/images/bookmarkFilled.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const BookMarkFilled = { sm: ( @@ -28,3 +26,5 @@ export default { ), } + +export default BookMarkFilled diff --git a/apps/tx-builder/src/components/Icon/images/check.tsx b/apps/tx-builder/src/components/Icon/images/check.tsx index 4487379d6..da0c7925c 100644 --- a/apps/tx-builder/src/components/Icon/images/check.tsx +++ b/apps/tx-builder/src/components/Icon/images/check.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const Check = { sm: ( @@ -24,3 +22,5 @@ export default { ), } + +export default Check diff --git a/apps/tx-builder/src/components/Icon/images/code.tsx b/apps/tx-builder/src/components/Icon/images/code.tsx index dda613230..10b25bbf8 100644 --- a/apps/tx-builder/src/components/Icon/images/code.tsx +++ b/apps/tx-builder/src/components/Icon/images/code.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const Code = { sm: ( @@ -25,3 +23,5 @@ export default { ), } + +export default Code diff --git a/apps/tx-builder/src/components/Icon/images/copy.tsx b/apps/tx-builder/src/components/Icon/images/copy.tsx index d3a07d584..652ff813e 100644 --- a/apps/tx-builder/src/components/Icon/images/copy.tsx +++ b/apps/tx-builder/src/components/Icon/images/copy.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const Copy = { sm: ( @@ -26,3 +24,5 @@ export default { ), } + +export default Copy diff --git a/apps/tx-builder/src/components/Icon/images/cross.tsx b/apps/tx-builder/src/components/Icon/images/cross.tsx index 30b62cb84..6c9eb6758 100644 --- a/apps/tx-builder/src/components/Icon/images/cross.tsx +++ b/apps/tx-builder/src/components/Icon/images/cross.tsx @@ -1,6 +1,6 @@ import React from 'react' -export default { +const Cross = { sm: ( @@ -24,3 +24,5 @@ export default { ), } + +export default Cross diff --git a/apps/tx-builder/src/components/Icon/images/delete.tsx b/apps/tx-builder/src/components/Icon/images/delete.tsx index 91e472c3f..8a60a4bbc 100644 --- a/apps/tx-builder/src/components/Icon/images/delete.tsx +++ b/apps/tx-builder/src/components/Icon/images/delete.tsx @@ -1,30 +1,54 @@ -import React from 'react' - -export default { +const Delete = { sm: ( - - - - - + + + + ), md: ( - - - - - - + + + + ), } + +export default Delete diff --git a/apps/tx-builder/src/components/Icon/images/edit.tsx b/apps/tx-builder/src/components/Icon/images/edit.tsx index e1286ad05..aa21ab2e8 100644 --- a/apps/tx-builder/src/components/Icon/images/edit.tsx +++ b/apps/tx-builder/src/components/Icon/images/edit.tsx @@ -1,26 +1,24 @@ -import React from 'react' - -export default { +const Edit = { sm: ( - - - - - + + ), md: ( - - - - - + + ), } + +export default Edit diff --git a/apps/tx-builder/src/components/Icon/images/externalLink.tsx b/apps/tx-builder/src/components/Icon/images/externalLink.tsx index 11e22ebdb..0e80e8874 100644 --- a/apps/tx-builder/src/components/Icon/images/externalLink.tsx +++ b/apps/tx-builder/src/components/Icon/images/externalLink.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const ExternalLink = { sm: ( @@ -34,3 +32,5 @@ export default { ), } + +export default ExternalLink diff --git a/apps/tx-builder/src/components/Icon/images/import.tsx b/apps/tx-builder/src/components/Icon/images/import.tsx index c7dd3c43b..906cd8da6 100644 --- a/apps/tx-builder/src/components/Icon/images/import.tsx +++ b/apps/tx-builder/src/components/Icon/images/import.tsx @@ -1,36 +1,36 @@ -import React from 'react' - -export default { +const Import = { sm: ( - + ), md: ( - + ), } + +export default Import diff --git a/apps/tx-builder/src/components/Icon/images/info.tsx b/apps/tx-builder/src/components/Icon/images/info.tsx index 0f546863f..3c1485c86 100644 --- a/apps/tx-builder/src/components/Icon/images/info.tsx +++ b/apps/tx-builder/src/components/Icon/images/info.tsx @@ -1,6 +1,4 @@ -import React from 'react' - -export default { +const Info = { sm: ( @@ -38,3 +36,5 @@ export default { ), } + +export default Info diff --git a/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx b/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx index 9cb6ef82e..43b1d071b 100644 --- a/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx +++ b/apps/tx-builder/src/components/Icon/images/termsOfUse.tsx @@ -1,26 +1,24 @@ -import React from 'react' - -export default { +const TermsOfUse = { sm: ( - - - - - + + ), md: ( - - - - - + + ), } + +export default TermsOfUse diff --git a/apps/tx-builder/src/components/Icon/index.tsx b/apps/tx-builder/src/components/Icon/index.tsx index 86187756b..0830ccf30 100644 --- a/apps/tx-builder/src/components/Icon/index.tsx +++ b/apps/tx-builder/src/components/Icon/index.tsx @@ -1,85 +1,22 @@ import React from 'react' import styled from 'styled-components' -import add from './images/add' -import addressBook from './images/addressBook' -import addressBookAdd from './images/addressBookAdd' +import { type Theme } from '@material-ui/core/styles' +import { Tooltip } from '../Tooltip' + import alert from './images/alert' -import allowances from './images/allowances' -import apps from './images/apps' -import arrowUp from './images/arrowUp' -import arrowRight from './images/arrowRight' -import arrowDown from './images/arrowDown' -import arrowLeft from './images/arrowLeft' -import assets from './images/assets' -import awaitingConfirmations from './images/awaitingConfirmations' import bookmark from './images/bookmark' import bookmarkFilled from './images/bookmarkFilled' -import camera from './images/camera' -import chain from './images/chain' import check from './images/check' -import circleCheck from './images/circleCheck' -import circleCross from './images/circleCross' -import circleDropdown from './images/circleDropdown' import code from './images/code' -import collectibles from './images/collectibles' import copy from './images/copy' import cross from './images/cross' -import currency from './images/currency' import deleteIcon from './images/delete' -import devicePassword from './images/devicePassword' import edit from './images/edit' -import error from './images/error' -import eth from './images/eth' -import exportImg from './images/export' import externalLink from './images/externalLink' -import eye from './images/eye' -import eyeOff from './images/eyeOff' -import filledCross from './images/filledCross' -import fingerPrint from './images/fingerPrint' -import fuelIndicator from './images/fuelIndicator' -import getInTouch from './images/getInTouch' -import gift from './images/gift' -import home from './images/home' import importImg from './images/import' import info from './images/info' -import knowledge from './images/knowledge' -import licenses from './images/licenses' -import loadSafe from './images/loadSafe' -import locked from './images/locked' -import mobileConfirm from './images/mobileConfirm' -import noInternet from './images/noInternet' -import owners from './images/owners' -import paste from './images/paste' -import paymentToken from './images/paymentToken' -import privacyPolicy from './images/privacyPolicy' -import qrCode from './images/qrCode' -import question from './images/question' -import rateApp from './images/rateApp' -import received from './images/received' -import recover from './images/recover' -import replaceOwner from './images/replaceOwner' -import requiredConfirmations from './images/requiredConfirmations' -import restricted from './images/restricted' -import resync from './images/resync' -import rocket from './images/rocket' -import safe from './images/safe' -import scan from './images/scan' -import search from './images/search' -import sendAgain from './images/sendAgain' -import sent from './images/sent' -import serverError from './images/serverError' -import settings from './images/settings' -import settingsChange from './images/settingsChange' -import settingsTool from './images/settingsTool' -import share from './images/share' import termsOfUse from './images/termsOfUse' -import transactionsInactive from './images/transactionsInactive' -import unlocked from './images/unlocked' -import userEdit from './images/userEdit' -import wallet from './images/wallet' -import { type Theme } from '@material-ui/core/styles' -import { Tooltip } from '../Tooltip' const StyledIcon = styled.span<{ color?: keyof Theme['palette'] }>` display: inline-flex; @@ -94,83 +31,19 @@ const StyledIcon = styled.span<{ color?: keyof Theme['palette'] }>` ` const icons = { - add, - addressBook, - addressBookAdd, alert, - allowances, - apps, - arrowUp, - arrowLeft, - arrowDown, - arrowRight, - assets, - awaitingConfirmations, bookmark, bookmarkFilled, - camera, - chain, check, - circleCheck, - circleCross, - circleDropdown, - code, - collectibles, copy, + code, cross, - currency, delete: deleteIcon, - devicePassword, edit, - error, - eth, - exportImg, externalLink, - eye, - eyeOff, - filledCross, - fingerPrint, - fuelIndicator, - getInTouch, - gift, - home, importImg, info, - knowledge, - licenses, - loadSafe, - locked, - mobileConfirm, - noInternet, - owners, - paste, - paymentToken, - privacyPolicy, - qrCode, - question, - rateApp, - received, - recover, - replaceOwner, - requiredConfirmations, - restricted, - resync, - rocket, - safe, - scan, - search, - sendAgain, - sent, - serverError, - settings, - settingsChange, - settingsTool, - share, termsOfUse, - transactionsInactive, - unlocked, - userEdit, - wallet, } export type IconType = typeof icons diff --git a/apps/tx-builder/src/components/QuickTip.tsx b/apps/tx-builder/src/components/QuickTip.tsx index ac1a46c48..b3382bc79 100644 --- a/apps/tx-builder/src/components/QuickTip.tsx +++ b/apps/tx-builder/src/components/QuickTip.tsx @@ -1,8 +1,7 @@ -import { Icon } from '@gnosis.pm/safe-react-components' import MuiAlert from '@material-ui/lab/Alert' import MuiAlertTitle from '@material-ui/lab/AlertTitle' -import React from 'react' import styled from 'styled-components' +import { Icon } from './Icon' type QuickTipProps = { onClose: () => void @@ -23,11 +22,10 @@ const QuickTip = ({ onClose }: QuickTipProps) => { const StyledAlert = styled(MuiAlert)` && { - font-family: 'Averta'; font-size: 14px; padding: 24px; - background: #eaf7f4; - color: #566976; + background: ${({ theme }) => theme.palette.secondary.background}; + color: ${({ theme }) => theme.palette.text.primary}; border-radius: 8px; .MuiAlert-action { diff --git a/apps/tx-builder/src/components/ShowMoreText.tsx b/apps/tx-builder/src/components/ShowMoreText.tsx index 83e150bbc..b920d99e3 100644 --- a/apps/tx-builder/src/components/ShowMoreText.tsx +++ b/apps/tx-builder/src/components/ShowMoreText.tsx @@ -1,5 +1,5 @@ import { useState, SyntheticEvent } from 'react' -import { Link } from '@gnosis.pm/safe-react-components' +import Link from './Link' type ShowMoreTextProps = { children: string diff --git a/apps/tx-builder/src/components/TransactionBatchListItem.tsx b/apps/tx-builder/src/components/TransactionBatchListItem.tsx index 53785d6ce..1254ca7da 100644 --- a/apps/tx-builder/src/components/TransactionBatchListItem.tsx +++ b/apps/tx-builder/src/components/TransactionBatchListItem.tsx @@ -1,13 +1,3 @@ -import { - Accordion, - AccordionSummary, - Dot, - EthHashInfo, - FixedIcon, - Icon, - Text, - Tooltip, -} from '@gnosis.pm/safe-react-components' import { AccordionDetails, IconButton } from '@material-ui/core' import { memo, useState } from 'react' import { DraggableProvided, DraggableStateSnapshot } from 'react-beautiful-dnd' @@ -16,6 +6,13 @@ import DragIndicatorIcon from '@material-ui/icons/DragIndicator' import { ProposedTransaction } from '../typings/models' import TransactionDetails from './TransactionDetails' import { getTransactionText } from '../utils' +import Text from './Text' +import { Accordion, AccordionSummary } from './Accordion' +import { Tooltip } from './Tooltip' +import EthHashInfo from './ETHHashInfo' +import { Icon } from './Icon' +import FixedIcon from './FixedIcon' +import Dot from './Dot' const UNKNOWN_POSITION_LABEL = '?' const minArrowSize = '12' @@ -86,8 +83,8 @@ const TransactionBatchListItem = memo( {/* Transacion Position */} - - {displayedTxPosition} + + {displayedTxPosition} {showArrowAdornment && } @@ -107,19 +104,13 @@ const TransactionBatchListItem = memo( > {/* Drag & Drop Indicator */} {reorderTransactions && ( - + )} {/* Destination Address label */} - {/* Transaction Description label */} - {transactionDescription} + {transactionDescription} {/* Transaction Actions */} {/* Edit transaction */} {replaceTransaction && ( - + + { event.stopPropagation() @@ -177,7 +162,6 @@ const TransactionBatchListItem = memo( placement="top" title="Expand transaction details" backgroundColor="primary" - textColor="white" arrow > (isDragging ? '#92c9be' : ' #e2e3e3')}; + background-color: #e2e3e3; transition: background-color 0.5s linear; ` @@ -301,27 +285,35 @@ const StyledAccordion = styled(Accordion).withConfig({ &.MuiAccordion-root { margin-bottom: 0; - border-color: ${({ isDragging, expanded }) => (isDragging || expanded ? '#92c9be' : '#e8e7e6')}; + border-width: 1px; + border-color: ${({ isDragging, expanded, theme }) => + isDragging || expanded ? theme.palette.secondary.light : theme.palette.common.white}; transition: border-color 0.5s linear; + + &:hover { + border-color: ${({ theme }) => theme.palette.secondary.light}; + + .MuiAccordionSummary-root { + background-color: ${({ theme }) => theme.palette.secondary.background}; + } + } } .MuiAccordionSummary-root { height: 52px; padding: 0px 8px; - background-color: ${({ isDragging }) => (isDragging ? '#EFFAF8' : '#FFFFFF')}; - - &:hover { - background-color: #ffffff; - } + background-color: ${({ isDragging, theme }) => + isDragging ? theme.palette.secondary.background : theme.palette.common.white}; .MuiIconButton-root { padding: 8px; } &.Mui-expanded { - background-color: #effaf8; - border-color: ${({ isDragging, expanded }) => - isDragging || expanded ? '#92c9be' : '#e8e7e6'}; + border-width: 1px; + background-color: ${({ theme }) => theme.palette.secondary.background}; + border-color: ${({ isDragging, expanded, theme }) => + isDragging || expanded ? theme.palette.secondary.light : '#e8e7e6'}; } } @@ -338,12 +330,15 @@ const TransactionActionButton = styled(IconButton)` ` const TransactionsDescription = styled(Text)` - flex-grow: 1; - padding-left: 24px; - - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + && { + flex-grow: 1; + padding-left: 24px; + font-size: 14px; + + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } ` const DragAndDropIndicatorIcon = styled(DragIndicatorIcon)` @@ -351,4 +346,10 @@ const DragAndDropIndicatorIcon = styled(DragIndicatorIcon)` margin-right: 4px; ` +const StyledEthHashInfo = styled(EthHashInfo)` + p { + font-size: 14px; + } +` + export default TransactionBatchListItem diff --git a/apps/tx-builder/src/components/TransactionDetails.tsx b/apps/tx-builder/src/components/TransactionDetails.tsx index 5aaeb1c67..46e3b209d 100644 --- a/apps/tx-builder/src/components/TransactionDetails.tsx +++ b/apps/tx-builder/src/components/TransactionDetails.tsx @@ -1,10 +1,13 @@ -import { ButtonLink, EthHashInfo, Text, Title } from '@gnosis.pm/safe-react-components' import React, { useEffect, useState } from 'react' import styled from 'styled-components' import useElementHeight from '../hooks/useElementHeight/useElementHeight' import { ProposedTransaction } from '../typings/models' import { weiToEther } from '../utils' +import EthHashInfo from './ETHHashInfo' +import Text from './Text' +import { Typography } from '@material-ui/core' +import ButtonLink from './buttons/ButtonLink' type TransactionDetailsProp = { transaction: ProposedTransaction @@ -29,13 +32,13 @@ const TransactionDetails = ({ transaction }: TransactionDetailsProp) => { return ( - + {isTokenTransferTx ? `Transfer ${weiToEther(value)} ${nativeCurrencySymbol} to:` : 'Interact with:'} - { {/* to address */} - - to (address) - - to (address) + { /> {/* value */} - - value: - + value: {`${weiToEther(value)} ${nativeCurrencySymbol}`} {/* data */} - - data: - + data: {data} {isContractInteractionTx && ( <> {/* method */} - - method: - - {contractMethod.name} + method: + {contractMethod.name} {/* method inputs */} {contractMethod.inputs.map(({ name, type }, index) => { @@ -84,7 +79,7 @@ const TransactionDetails = ({ transaction }: TransactionDetailsProp) => { return ( {/* input name */} - + {inputLabel} {/* input value */} @@ -115,11 +110,19 @@ const TxSummaryContainer = styled.div` margin-top: 16px; ` -const StyledTxTitle = styled(Title)` - font-size: 16px; - margin: 8px 0; - font-weight: bold; - line-height: initial; +const StyledTxTitle = styled(Typography)` + && { + font-size: 16px; + margin: 8px 0; + font-weight: bold; + line-height: initial; + } +` +const StyledText = styled(Text)` + && { + color: ${({ theme }) => theme.palette.text.secondary}; + font-weight: 400; + } ` const StyledMethodNameLabel = styled(Text)` @@ -152,7 +155,7 @@ const TxValueLabel = ({ children }: { children: React.ReactNode }) => { return (
{/* value */} - + {children} @@ -169,21 +172,28 @@ const TxValueLabel = ({ children }: { children: React.ReactNode }) => { const StyledTxValueLabel = styled(Text).withConfig({ shouldForwardProp: prop => !['showMore'].includes(prop) || !['showEllipsis'].includes(prop), })<{ showMore?: boolean; showEllipsis?: boolean }>` - max-height: ${({ showMore }) => (showMore ? '100%' : `${MAX_HEIGHT + 1}px`)}; - - line-break: anywhere; - overflow: hidden; - word-break: break-all; - text-overflow: ellipsis; - - ${({ showEllipsis, showMore }) => - !showMore && - showEllipsis && - `@supports (-webkit-line-clamp: 2) { + && { + max-height: ${({ showMore }) => (showMore ? '100%' : `${MAX_HEIGHT + 1}px`)}; + font-size: 14px; + line-break: anywhere; + overflow: hidden; + word-break: break-all; + text-overflow: ellipsis; + + ${({ showEllipsis, showMore }) => + !showMore && + showEllipsis && + `@supports (-webkit-line-clamp: 2) { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }`} + } +` +const StyledEthHashInfo = styled(EthHashInfo)` + p { + font-size: 14px; + } ` const StyledButtonLink = styled(ButtonLink)` diff --git a/apps/tx-builder/src/components/TransactionsBatchList.tsx b/apps/tx-builder/src/components/TransactionsBatchList.tsx index f2382b911..7fdf31a76 100644 --- a/apps/tx-builder/src/components/TransactionsBatchList.tsx +++ b/apps/tx-builder/src/components/TransactionsBatchList.tsx @@ -1,5 +1,4 @@ import { isValidElement, useMemo, useState } from 'react' -import { Dot, Text, Title, Icon, Tooltip } from '@gnosis.pm/safe-react-components' import IconButton from '@material-ui/core/IconButton' import styled from 'styled-components' @@ -25,6 +24,11 @@ import Item from './TransactionBatchListItem' import VirtualizedList from './VirtualizedList' import { getTransactionText } from '../utils' import { EditableLabelProps } from './EditableLabel' +import Text from './Text' +import { Tooltip } from './Tooltip' +import { Icon } from './Icon' +import { Typography } from '@material-ui/core' +import Dot from './Dot' type TransactionsBatchListProps = { transactions: ProposedTransaction[] @@ -142,28 +146,16 @@ const TransactionsBatchList = ({ {showBatchHeader && ( {/* Transactions Batch Counter */} - - - {transactions.length} - + + {transactions.length} {/* Transactions Batch Title */} - {batchTitle && ( - - {batchTitle} - - )} + {batchTitle && {batchTitle}} {/* Transactions Batch Actions */} {saveBatch && ( - + )} {downloadBatch && ( - + downloadBatch(fileName, transactions)}> @@ -189,13 +175,7 @@ const TransactionsBatchList = ({ )} {removeAllTransactions && ( - + @@ -402,7 +382,6 @@ const TransactionsBatchWrapper = styled.section` // batch header styles const TransactionHeader = styled.header` - margin-top: 24px; display: flex; align-items: center; ` @@ -411,18 +390,19 @@ const TransactionCounterDot = styled(Dot)` height: 24px; width: 24px; min-width: 24px; - background-color: #566976; ` -const TransactionsTitle = styled(Title)` - flex-grow: 1; - margin-left: 14px; - min-width: 0; +const TransactionsTitle = styled(Typography)` + && { + flex-grow: 1; + margin-left: 14px; + min-width: 0; - font-size: 16px; - line-height: normal; - display: flex; - align-items: center; + font-size: 16px; + line-height: normal; + display: flex; + align-items: center; + } ` const StyledHeaderIconButton = styled(IconButton)` diff --git a/apps/tx-builder/src/components/forms/AddNewTransactionForm.tsx b/apps/tx-builder/src/components/forms/AddNewTransactionForm.tsx index e5df78724..88fc08993 100644 --- a/apps/tx-builder/src/components/forms/AddNewTransactionForm.tsx +++ b/apps/tx-builder/src/components/forms/AddNewTransactionForm.tsx @@ -1,4 +1,3 @@ -import { Title, Button } from '@gnosis.pm/safe-react-components' import styled from 'styled-components' import { ContractInterface } from '../../typings/models' @@ -10,6 +9,9 @@ import SolidityForm, { parseFormToProposedTransaction, } from './SolidityForm' import { useTransactions, useNetwork } from '../../store' +import { Typography } from '@material-ui/core' +import Button from '../Button' +import FixedIcon from '../FixedIcon' type AddNewTransactionFormProps = { contract: ContractInterface | null @@ -43,7 +45,9 @@ const AddNewTransactionForm = ({ return ( <> - Transaction information + + Transaction information + {/* Add transaction btn */} - @@ -68,8 +73,19 @@ const AddNewTransactionForm = ({ export default AddNewTransactionForm +const StyledButtonLabel = styled.span` + margin-left: 8px; +` const ButtonContainer = styled.div` display: flex; justify-content: space-between; margin-top: 15px; + + .MuiButton-root { + padding-left: 10px; + } + + span { + display: flex; + } ` diff --git a/apps/tx-builder/src/components/forms/fields/AddressContractField.tsx b/apps/tx-builder/src/components/forms/fields/AddressContractField.tsx index 194c74be5..134bbf5ee 100644 --- a/apps/tx-builder/src/components/forms/fields/AddressContractField.tsx +++ b/apps/tx-builder/src/components/forms/fields/AddressContractField.tsx @@ -1,5 +1,5 @@ import { ReactElement } from 'react' -import { AddressInput } from '@gnosis.pm/safe-react-components' +import AddressInput from './AddressInput' const AddressContractField = ({ id, diff --git a/apps/tx-builder/src/components/forms/fields/JsonField.tsx b/apps/tx-builder/src/components/forms/fields/JsonField.tsx index 8c4c86e77..b5d1036c9 100644 --- a/apps/tx-builder/src/components/forms/fields/JsonField.tsx +++ b/apps/tx-builder/src/components/forms/fields/JsonField.tsx @@ -1,17 +1,12 @@ import { useState, useCallback, ClipboardEvent } from 'react' import styled from 'styled-components' -import { - Icon, - TextFieldInput, - Tooltip, - GenericModal, - Text, - Button, - IconTypes, -} from '@gnosis.pm/safe-react-components' import IconButton from '@material-ui/core/IconButton' -import { Box } from '@material-ui/core' +import { Box, Button, Tooltip } from '@material-ui/core' import useModal from '../../../hooks/useModal/useModal' +import { Icon, IconTypes } from '../../Icon' +import Text from '../../Text' +import GenericModal from '../../GenericModal' +import TextFieldInput from './TextFieldInput' const DEFAULT_ROWS = 4 @@ -113,17 +108,17 @@ const JsonField = ({ id, name, label, value, onChange }: Props) => { - Do you want to replace the current ABI? + Do you want to replace the current ABI? } onClose={toggleModal} title="Replace ABI" footer={ - - @@ -159,7 +154,7 @@ const IconContainerButton = ({ }) => ( - + ) @@ -173,7 +168,7 @@ const IconContainer = styled.div<{ error: boolean }>` top: -10px; right: 15px; border: 1px solid - ${({ theme, error }) => (error ? theme.colors.error : theme.colors.inputDefault)}; + ${({ theme, error }) => (error ? theme.palette.error.main : theme.palette.primary.main)}; border-radius: 50%; background-color: #fff; ` diff --git a/apps/tx-builder/src/components/forms/fields/SelectContractField.tsx b/apps/tx-builder/src/components/forms/fields/SelectContractField.tsx index c6016f586..45ddb69dd 100644 --- a/apps/tx-builder/src/components/forms/fields/SelectContractField.tsx +++ b/apps/tx-builder/src/components/forms/fields/SelectContractField.tsx @@ -1,7 +1,7 @@ import Autocomplete from '@mui/material/Autocomplete' -import { TextFieldInput } from '@gnosis.pm/safe-react-components' import { SelectItem } from '@gnosis.pm/safe-react-components/dist/inputs/Select' import { type SyntheticEvent, useCallback, useMemo } from 'react' +import TextFieldInput from './TextFieldInput' type SelectContractFieldTypes = { options: SelectItem[] diff --git a/apps/tx-builder/src/components/forms/fields/TextContractField.tsx b/apps/tx-builder/src/components/forms/fields/TextContractField.tsx index 544273d5d..693c50a72 100644 --- a/apps/tx-builder/src/components/forms/fields/TextContractField.tsx +++ b/apps/tx-builder/src/components/forms/fields/TextContractField.tsx @@ -1,6 +1,5 @@ -import { TextFieldInput } from '@gnosis.pm/safe-react-components' -import { TextFieldInputProps } from '@gnosis.pm/safe-react-components/dist/inputs/TextFieldInput' import styled from 'styled-components' +import TextFieldInput, { TextFieldInputProps } from './TextFieldInput' type TextContractFieldTypes = TextFieldInputProps & { networkPrefix?: undefined | string diff --git a/apps/tx-builder/src/components/forms/fields/TextareaContractField.tsx b/apps/tx-builder/src/components/forms/fields/TextareaContractField.tsx index f5be176ad..dce59f50d 100644 --- a/apps/tx-builder/src/components/forms/fields/TextareaContractField.tsx +++ b/apps/tx-builder/src/components/forms/fields/TextareaContractField.tsx @@ -1,5 +1,5 @@ -import { TextFieldInputProps } from '@gnosis.pm/safe-react-components/dist/inputs/TextFieldInput' import TextContractField from './TextContractField' +import { TextFieldInputProps } from './TextFieldInput' const DEFAULT_ROWS = 4 diff --git a/apps/tx-builder/src/components/modals/DeleteBatchFromLibrary.tsx b/apps/tx-builder/src/components/modals/DeleteBatchFromLibrary.tsx index 3409f8a14..6accf41d2 100644 --- a/apps/tx-builder/src/components/modals/DeleteBatchFromLibrary.tsx +++ b/apps/tx-builder/src/components/modals/DeleteBatchFromLibrary.tsx @@ -1,8 +1,11 @@ -import { Dot, Text, Button, GenericModal } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' import { Batch } from '../../typings/models' +import GenericModal from '../GenericModal' +import Text from '../Text' +import Button from '../Button' +import Dot from '../Dot' type DeleteBatchFromLibraryProps = { batch: Batch @@ -17,28 +20,21 @@ const DeleteBatchFromLibrary = ({ batch, onClick, onClose }: DeleteBatchFromLibr withoutBodyPadding body={ - - - {batch.transactions.length} - + + {batch.transactions.length} - {`${batch.name} batch will be permanently deleted`} + {`${batch.name} batch will be permanently deleted`} - - @@ -58,13 +54,15 @@ const StyledModalBodyWrapper = styled.div` ` const StyledModalDot = styled(Dot)` - height: 24px; - width: 24px; - min-width: 24px; - background-color: #566976; + && { + height: 24px; + width: 24px; + min-width: 24px; + background-color: #566976; - position: absolute; - top: 22px; + position: absolute; + top: 22px; + } ` const StyledModalText = styled(Text)` diff --git a/apps/tx-builder/src/components/modals/DeleteBatchModal.tsx b/apps/tx-builder/src/components/modals/DeleteBatchModal.tsx index 00a61cdeb..9e5950316 100644 --- a/apps/tx-builder/src/components/modals/DeleteBatchModal.tsx +++ b/apps/tx-builder/src/components/modals/DeleteBatchModal.tsx @@ -1,6 +1,9 @@ -import { Dot, Text, Button, GenericModal } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' +import GenericModal from '../GenericModal' +import Text from '../Text' +import Button from '../Button' +import Dot from '../Dot' type DeleteBatchModalProps = { count: number @@ -15,25 +18,21 @@ const DeleteBatchModal = ({ count, onClick, onClose }: DeleteBatchModalProps) => withoutBodyPadding body={ - - - {count} - + + {count} - - {`transaction${count > 1 ? 's' : ''}`} will be cleared - + {`transaction${count > 1 ? 's' : ''}`} will be cleared - - diff --git a/apps/tx-builder/src/components/modals/DeleteTransactionModal.tsx b/apps/tx-builder/src/components/modals/DeleteTransactionModal.tsx index fd0bc20bc..fb64d4af3 100644 --- a/apps/tx-builder/src/components/modals/DeleteTransactionModal.tsx +++ b/apps/tx-builder/src/components/modals/DeleteTransactionModal.tsx @@ -1,6 +1,9 @@ -import { Dot, Text, Button, GenericModal } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' +import GenericModal from '../GenericModal' +import Text from '../Text' +import Button from '../Button' +import Dot from '../Dot' type DeleteTransactionModalProps = { txIndex: number @@ -22,23 +25,21 @@ const DeleteTransactionModal = ({ withoutBodyPadding body={ - - - {positionLabel} - + + {positionLabel} - {`${txDescription} will be permanently deleted from the batch`} + {`${txDescription} will be permanently deleted from the batch`} - - diff --git a/apps/tx-builder/src/components/modals/EditTransactionModal.tsx b/apps/tx-builder/src/components/modals/EditTransactionModal.tsx index 203e5b0b9..1dd29f282 100644 --- a/apps/tx-builder/src/components/modals/EditTransactionModal.tsx +++ b/apps/tx-builder/src/components/modals/EditTransactionModal.tsx @@ -1,4 +1,3 @@ -import { GenericModal, Button } from '@gnosis.pm/safe-react-components' import styled from 'styled-components' import { ProposedTransaction } from '../../typings/models' import SolidityForm, { @@ -11,6 +10,8 @@ import SolidityForm, { TO_ADDRESS_FIELD_NAME, } from '../forms/SolidityForm' import { weiToEther } from '../../utils' +import GenericModal from '../GenericModal' +import Button from '../Button' type EditTransactionModalProps = { txIndex: number @@ -78,12 +79,12 @@ const EditTransactionModal = ({ > {/* Remove transaction btn */} - {/* Add transaction btn */} - diff --git a/apps/tx-builder/src/components/modals/ImplementationABIDialog.tsx b/apps/tx-builder/src/components/modals/ImplementationABIDialog.tsx index 7cd0c2f6a..1f7ef59e2 100644 --- a/apps/tx-builder/src/components/modals/ImplementationABIDialog.tsx +++ b/apps/tx-builder/src/components/modals/ImplementationABIDialog.tsx @@ -1,7 +1,10 @@ import React from 'react' -import { Text, Button, GenericModal, EthHashInfo } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' +import Text from '../Text' +import Button from '../Button' +import EthHashInfo from '../ETHHashInfo' +import GenericModal from '../GenericModal' type Props = { networkPrefix: string @@ -24,9 +27,7 @@ const ImplementationABIDialog: React.FC = ({ withoutBodyPadding body={ - - The contract looks like a proxy. Do you want to use the Implementation ABI? - + The contract looks like a proxy. Do you want to use the Implementation ABI? = ({ justifyContent="center" maxWidth="470px" > - - diff --git a/apps/tx-builder/src/components/modals/SaveBatchModal.tsx b/apps/tx-builder/src/components/modals/SaveBatchModal.tsx index 88c1f6f89..6fdf0fa64 100644 --- a/apps/tx-builder/src/components/modals/SaveBatchModal.tsx +++ b/apps/tx-builder/src/components/modals/SaveBatchModal.tsx @@ -1,4 +1,3 @@ -import { Button, GenericModal } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import { useForm, ValidateResult } from 'react-hook-form' import { useNavigate } from 'react-router-dom' @@ -9,6 +8,8 @@ import { useTransactionLibrary } from '../../store' import { Batch } from '../../typings/models' import Field from '../forms/fields/Field' import { TEXT_FIELD_TYPE } from '../forms/fields/fields' +import GenericModal from '../GenericModal' +import Button from '../Button' type SaveBatchModalProps = { onClick: (name: string) => void @@ -53,8 +54,8 @@ const SaveBatchModal = ({ onClick, onClose }: SaveBatchModalProps) => { control={control} showErrorsInTheLabel={false} /> - - diff --git a/apps/tx-builder/src/components/modals/SuccessBatchCreationModal.tsx b/apps/tx-builder/src/components/modals/SuccessBatchCreationModal.tsx index 22c23adb2..9f2b0e86b 100644 --- a/apps/tx-builder/src/components/modals/SuccessBatchCreationModal.tsx +++ b/apps/tx-builder/src/components/modals/SuccessBatchCreationModal.tsx @@ -1,8 +1,12 @@ -import { Dot, Text, Button, GenericModal, Title } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' import { ReactComponent as SuccessBatchSVG } from '../../assets/success-batch.svg' +import GenericModal from '../GenericModal' +import Text from '../Text' +import Button from '../Button' +import { Typography } from '@material-ui/core' +import Dot from '../Dot' type SuccessBatchCreationModalProps = { count: number @@ -26,25 +30,21 @@ const SuccessBatchCreationModal = ({ count, onClick, onClose }: SuccessBatchCrea {/* Title */} - Success! + Success! {/* Text */} - - - {count} - + + {count} - Transaction Batch in the queue. + Transaction Batch in the queue. - You can now sign and execute it. + You can now sign and execute it. {/* Button */} - + } onClose={onClose} @@ -58,9 +58,11 @@ const StyledBodyWrapper = styled(Box)` padding: 50px; ` -const StyledBodyTitle = styled(Title)` - font-size: 32px; - margin: 16px 0; +const StyledBodyTitle = styled(Typography)` + && { + font-size: 32px; + margin: 16px 0; + } ` const StyledTextWrapper = styled.div` diff --git a/apps/tx-builder/src/components/modals/WrongChainBatchModal.tsx b/apps/tx-builder/src/components/modals/WrongChainBatchModal.tsx index c6f79b22f..fe40f3f1c 100644 --- a/apps/tx-builder/src/components/modals/WrongChainBatchModal.tsx +++ b/apps/tx-builder/src/components/modals/WrongChainBatchModal.tsx @@ -1,6 +1,9 @@ -import { Button, GenericModal, Icon, Text } from '@gnosis.pm/safe-react-components' import Box from '@material-ui/core/Box' import styled from 'styled-components' +import GenericModal from '../GenericModal' +import { Icon } from '../Icon' +import Text from '../Text' +import Button from '../Button' type WrongChainBatchModalProps = { onClick: () => void @@ -25,7 +28,7 @@ const WrongChainBatchModal = ({ onClick, onClose, fileChainId }: WrongChainBatch withoutBodyPadding body={ - + This batch is from another Chain {fileChainId ? ` (${fileChainId})` : ''}! @@ -35,7 +38,7 @@ const WrongChainBatchModal = ({ onClick, onClose, fileChainId }: WrongChainBatch justifyContent="center" maxWidth={'450px'} > - diff --git a/apps/tx-builder/src/global.ts b/apps/tx-builder/src/global.ts index db2e02198..31d967e3b 100644 --- a/apps/tx-builder/src/global.ts +++ b/apps/tx-builder/src/global.ts @@ -1,6 +1,6 @@ import { createGlobalStyle } from 'styled-components' -import avertaFont from '@gnosis.pm/safe-react-components/dist/fonts/averta-normal.woff2' -import avertaBoldFont from '@gnosis.pm/safe-react-components/dist/fonts/averta-bold.woff2' +import DMSansFont from './assets/fonts/DMSansRegular.woff2' +import DMSansBoldFont from './assets/fonts/DMSans700.woff2' const GlobalStyle = createGlobalStyle` html { @@ -17,12 +17,19 @@ const GlobalStyle = createGlobalStyle` #root { height: 100%; } + + @font-face { + font-family: 'DM Sans'; + font-display: swap; + font-weight: 400; + src: url(${DMSansFont}) format('woff2'); + } @font-face { - font-family: 'Averta'; - src: local('Averta'), local('Averta Bold'), - url(${avertaFont}) format('woff2'), - url(${avertaBoldFont}) format('woff'); + font-family: 'DM Sans'; + font-display: swap; + font-weight: bold; + src: url(${DMSansBoldFont}) format('woff2'); } input:-webkit-autofill, diff --git a/apps/tx-builder/src/index.tsx b/apps/tx-builder/src/index.tsx index 13b2b2994..32049448e 100644 --- a/apps/tx-builder/src/index.tsx +++ b/apps/tx-builder/src/index.tsx @@ -1,6 +1,4 @@ import ReactDOM from 'react-dom' -import { ThemeProvider } from 'styled-components' -import { theme } from '@gnosis.pm/safe-react-components' import { SafeProvider } from '@safe-global/safe-apps-react-sdk' import { BrowserRouter } from 'react-router-dom' @@ -9,19 +7,25 @@ import * as serviceWorker from './serviceWorker' import GlobalStyles from './global' import App from './App' import StoreProvider from './store' +import SafeThemeProvider from './theme/SafeThemeProvider' +import { ThemeProvider } from 'styled-components' ReactDOM.render( <> - - - - - - - - - + + {theme => ( + + + + + + + + + + )} + , document.getElementById('root'), ) diff --git a/apps/tx-builder/src/pages/CreateTransactions.tsx b/apps/tx-builder/src/pages/CreateTransactions.tsx index 6cfd73535..b8cb7d3c1 100644 --- a/apps/tx-builder/src/pages/CreateTransactions.tsx +++ b/apps/tx-builder/src/pages/CreateTransactions.tsx @@ -1,15 +1,16 @@ import { useState } from 'react' import { useNavigate } from 'react-router-dom' import styled from 'styled-components' -import { Button, Tooltip } from '@gnosis.pm/safe-react-components' import Grid from '@material-ui/core/Grid' -import TransactionsBatchList from '../components/TransactionsBatchList' -import CreateNewBatchCard from '../components/CreateNewBatchCard' import { CREATE_BATCH_PATH, REVIEW_AND_CONFIRM_PATH } from '../routes/routes' import QuickTip from '../components/QuickTip' import { useNetwork, useTransactionLibrary, useTransactions } from '../store' import useModal from '../hooks/useModal/useModal' +import Button from '../components/Button' +import { Tooltip } from '../components/Tooltip' +import CreateNewBatchCard from '../components/CreateNewBatchCard' +import TransactionsBatchList from '../components/TransactionsBatchList' import WrongChainBatchModal from '../components/modals/WrongChainBatchModal' const CreateTransactions = () => { @@ -56,7 +57,6 @@ const CreateTransactions = () => { /> {/* Go to Review Screen button */} )} @@ -139,21 +128,17 @@ const ReviewAndConfirm = () => { {simulationRequestStatus === FETCH_STATUS.ERROR && ( - - An unexpected error occurred during simulation. - + An unexpected error occurred during simulation. )} {simulationRequestStatus === FETCH_STATUS.LOADING && ( <> - - Running simulation... - + Running simulation... )} @@ -166,15 +151,14 @@ const ReviewAndConfirm = () => { iconType="alert" iconColor="error" text="Failed" - textSize="lg" color="error" /> - + The batch failed during the simulation throwing error{' '} {simulation.transaction.error_message} in the contract at{' '} {simulation.transaction.error_info?.address}. Full simulation report is available{' '} - + on Tenderly . @@ -188,12 +172,11 @@ const ReviewAndConfirm = () => { iconType="check" iconColor="primary" text="Success" - textSize="lg" color="primary" /> - + The batch was successfully simulated. Full simulation report is available{' '} - + on Tenderly . @@ -236,15 +219,17 @@ const ReviewAndConfirm = () => { export default ReviewAndConfirm const StyledButton = styled(ButtonLink)` - position: absolute; - right: 26px; - padding: 5px; - width: 26px; - height: 26px; + && { + position: absolute; + right: 26px; + padding: 5px; + width: 26px; + height: 26px; - :hover { - background: ${({ theme }) => theme.colors.separator}; - border-radius: 16px; + :hover { + background: ${({ theme }) => theme.palette.divider}; + border-radius: 16px; + } } ` @@ -266,11 +251,14 @@ const Wrapper = styled.main` } ` -const StyledTitle = styled(Title)` - margin-top: 0px; - margin-bottom: 5px; - font-size: 20px; - line-height: normal; +const StyledTitle = styled(Typography)` + && { + margin-top: 0px; + margin-bottom: 1rem; + font-size: 20px; + font-weight: 700; + line-height: normal; + } ` const ButtonsWrapper = styled.div` diff --git a/apps/tx-builder/src/pages/SaveTransactionLibrary.tsx b/apps/tx-builder/src/pages/SaveTransactionLibrary.tsx index 5808ed672..10ea2a26d 100644 --- a/apps/tx-builder/src/pages/SaveTransactionLibrary.tsx +++ b/apps/tx-builder/src/pages/SaveTransactionLibrary.tsx @@ -2,12 +2,12 @@ import { useEffect } from 'react' import { useNavigate } from 'react-router-dom' import Grid from '@material-ui/core/Grid' import styled from 'styled-components' -import { Button } from '@gnosis.pm/safe-react-components' import TransactionsBatchList from '../components/TransactionsBatchList' import { useTransactionLibrary, useTransactions } from '../store' import { CREATE_BATCH_PATH, REVIEW_AND_CONFIRM_PATH, SAVE_BATCH_PATH } from '../routes/routes' import EditableLabel from '../components/EditableLabel' +import Button from '../components/Button' const SaveTransactionLibrary = () => { const { @@ -52,7 +52,6 @@ const SaveTransactionLibrary = () => { /> {/* Go to Review Screen button */}