From 3b5869cbc11c145765969fb94ccaf77ed32ecd10 Mon Sep 17 00:00:00 2001 From: codinsonn Date: Mon, 26 Jun 2023 19:02:50 +0200 Subject: [PATCH 1/2] wip: Attempt Modular Font Management --- apps/next/next.config.js | 1 + features/app-core/fonts/AntDesign.ttf | Bin 0 -> 70344 bytes features/app-core/fonts/registry.tsx | 38 +++++++++++ features/app-core/fonts/registry.web.tsx | 49 ++++++++++++++ features/app-core/hooks/useLoadFonts.ts | 78 +++++++++++++---------- features/app-core/tailwind.config.js | 39 ++++++------ packages/@registries/fonts.generated.ts | 8 +++ 7 files changed, 162 insertions(+), 51 deletions(-) create mode 100644 features/app-core/fonts/AntDesign.ttf create mode 100644 features/app-core/fonts/registry.tsx create mode 100644 features/app-core/fonts/registry.web.tsx create mode 100644 packages/@registries/fonts.generated.ts diff --git a/apps/next/next.config.js b/apps/next/next.config.js index ce381214..417bf6b7 100644 --- a/apps/next/next.config.js +++ b/apps/next/next.config.js @@ -78,6 +78,7 @@ const nextConfig = { experimental: { // appDir: true, // transpilePackages: transpiledModules, + forceSwcTransforms: true, }, } diff --git a/features/app-core/fonts/AntDesign.ttf b/features/app-core/fonts/AntDesign.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2abf03542c17e6f7a7806a226c3be732b51c5a40 GIT binary patch literal 70344 zcmeFa34B}CwKux=Ihw3l)@;d=C0UZ^Nw#Ijj_u5e6Oxb#NJtf zwNMB{p#yLWZ7E?0l!gRoDNx2z3bYKj(9^nb+dwHzd!v)@zs^2#d%rL7 z(wWa*ds_2ehjGT3jcsExYniop>C^|*9sk7`@50%s3l=xGE&J=-AsnBN<7FpoT)k=k zF}JQ~%ycPZWuSn+2KE-K(vIn@75^DKpdD-1aU5eP zVfxH@OYo$4vADuFoVPe+$>mSjz_3)}hZt{ek<%xD7bdKPpN_uhDiGaBXf>S`7PmBS4;04q>;G-@_Q1amT~;Y>|JUgXs$v8Xt!og~GE@m#CRgAr zQMCqaL49%FApHf$NrpWT$gRrX|7ag_5BY{tL+PQep#?)n4s9R0XXpn*&knsl^w|NT z)>{?!M|sFK+Qi^Nf%1WHMOZk^bgr)wuKegm)KeCbM_CmkNtrC2RoZ> zWj_L!eVd)b&SmGZ^VtRLLWT}w7qM;NX_v6Su`jbr*>Bhm_G9)Sdx$;2E@NL|m$NI_ zmFz0^RdzqSnthF3!>(o5vFq6l?Cb0s>_&DI`zE`Y-NLrBTiI>wc6JB*7Q2((#lFqH z!~T=~iT#B=#hzx*u)nfDv!Ah_vya%b>=*1g_B?xm{gS=NUScn^SJ=nwRrVVD6?>ii zn!UmP#r})!=aoFh<2=c;ypGrN6wmN#p5`^Ymc7fq%kE+KvWM9t?Dy<5_IIYT1DtWr zB`$LVH*ymg2**$E3LWK8+!Qy2cW26mw+TUg^mer&=Q4?0Yv&0Iwtx8I-}4rkvO!hLdO8i zSfQ*;1@Vu}u+RZP)=RbgKT&@ZOw07}Lb9YE8V zq64TKQ*;2GV~P%-cudg&w2vt|fC@522hc;N=m5&d6dgb#nW6*n4@C#iO{VAo3d$56 zKuejT1E?xfbO3#2iVmQ(Owj=}mnk}c`Z7fa&|#+N0E)~M9YC9zq64TjQ*;2mW{M7= z+)U8{G@L0qfSNN!2heq<=l}}O6dge8nW6(5z`hQk|4h*VoPa4hfG03T2XF_b=m0*! z6dk}Zn4$xC2UBza7h%e50pKT0nIiz4g(-sqz+;#)R{*#TQ|1W(-(kuT0>FWoGG73A z5mOcj09RtlLIL1UOgT~jI2BVC2_W53Su6nDiz!P4fR8a{sQ_>^rYsY{c4K>#0B|{` z94!F+jw#0o0Ow=Masl9hOj#iS+>j~93IJbZ%1Qy?kW5)60KAeZ#|Z$}WXkaZz(1L? zS^zjHQ`QIoPi4vp0>E9FvQ_~2EK^Pt0FKL)bppV9nX+C0xG+;r5&(Y8l#>O3Gc)BB z0pQV0IaL6-HB&YS0N-ZHMgid9OgT*ecsWx}7XYr#luZJ_-*9!Fy(v! zkSmySfdEJtOu0}1WDTZVBmhzeQ??0!{K1rq1wayE$|V9IlQ8AW0wA3*bBE@R5=0wAF=`eKU07&mld0hbHc&7YX z03>>*ydeOxJyWQU0g&>U@}>aD`%Iy641na%6dK0>=m1RltpI2PO!=Jv=mku9M*uVg zro1Zvx&l+)69BD&Dent_{=gK%2>?xkDZdv0oq{PJ2!M9Mln(_!&tS?Q1VH0piXs5I z2UGqi09puBsBQr0BTN|*0L_Fcgew3#3R4It0JIgR&@}+`7N-1{0BA5wp>_d4mthLk z833(@DSHJ#zhTNJ0-)(IG{Kem4pz$>x+OaPBz`*#66&Y)up;7M!^0(cf%qX1rq ztw{jM@P9N5;3;e^0(b`7G6B3ATdM$`#?~f)*I;WG0IiD+xdcG}Vnc2L(8Sn~R{(S} zHslik?TihfJOb!xYzXfqfX2p#x&%OXV?zrBK#OBTM+$&G$A&OB2%y=qAsR$?Fafpz&+T4 z{t)nTYgR?r^)^C%IqqoaEW=dB1#K`K9H*_cnQt_Fm$B z-Ph#1)c13LyMK%S`9NJ@L*V{kP4LX%u25U(`yn;FD*VInpDXT;B%`6|*2=!how0?n zyJMfm2dmnvZmRk$u_f_9(wRIZD`$?rZ@9=c2ahG_Vt?Hnw_-+ zwOec7uJhH+uKQuVss4%vYr}O7A2%*)ysGi{O>Iq=G(FTDXuhy{cS}pl-7TNBcD0_? z`be9lZFbvrZLj5gxrMo_a?j+{_Nnb(X@9=M*D=`f-HuN?kM7*rxi?>zzahW3tFPXiBzCuUq~0n)z$K zz2@^1)}8SB+UaYzpE&)*drwr>RjgaJ?t%5D^(`k2oOHvxRw^ zTQ=5h{Oq)+PW#vC(@)>IDYohEGp3*M;hAk`zP;JK`I;>lxnw0c@SpM%atL~O4fMk4 zB+qkGJx@BNN}kBJH%ax}pD_A^KBt^bWfSI9vPquIgGrMw(AL?W37X6%7tA{`o=dcK zW}Boe?`ZFndU#u)lJjt+VsUvoS}tG5t)Xn}GIdb;HuuLEXg{qo9W3K~ z+cxfvR5|bI_f&ZBcYZ~{TOKyM9hOjqBUSC=XMbo5dF_>%4`>d7N*#Dy?vrPdeV~kc z+BXG*muGaVjo%49u#oX_Gv^1EDq0`nMTW=3Xm`_!Pz z#fJjTlGH5l)Sf#ap6hHwOPI`wCOmf|J@@tEb7p~d@i}V4ZRn?Mcn(w?9L)^FH!Rl~ zCYw!7ytAKYn|L2=sR5tF-csK)nRw!@w|K&2Qr~O&$PP?wFTZT#{;2&Un|zT`eebQe z)%T1>o_HHK6+Zr*jR&K)r=GS|2DtSd8w3#1Z^bepsf;Mo$(wnmy`Oi+IHqPW29`Xk z(6u%cWw(87tJI4gTdK#Vm1Pr!KmC-gQX4B1l<75Pnz`A@n>dPXLq$zv%8c47txrE~ z)#_lavc6;GV++0A#%-^>f|jTRZiL>5GDo$o*KA6nqJ2CN=lMPmpfN?p-Vp@_iY1RJ zQEeCHpczED)V7dX^!^ONa@UF0Z9^jlF&3O0Wuh;$nNF0L@64BUb=I5BI0+Zr6{BWo zm)J3j7Mz<%@nquM1&bam**|7ff4ub{qenqLnLKB~q8*FopPR(L;oaGz28U6N9_*mv z=opEA{&4Y^edxD7j*dj#nqaR-A0BoE9>#bY9>>&s@?qD2yKEQ?fl3=hE=t9XpQxjXI1N)&E{U{O{MH&^2Bi zK!Y(MxGb?M#?oaN7k%*DfOY0`F;1-0oND64I#WqZ3OIN!R4;WJf+-hY=XYtm5PePea+rL-lWzrwXZjbV^i9CcG8cj4SAm}vnL`)`+ zSX<|0-ky;g8a7T=A2`zZOWeB&v3w>*U<$Xd-4W|FCha$o>JzKZh%q%c3pStL>!AyfFA zQfeH``s9xG3_p#pJlhtC+8?x9cY?B8&r$E0ykTjhKju$PStPA+(WXiL&Q@z6YTKdT zvy~syOZQ0A&bCJbwg+vMww+dx->r?yHuRFH)3j(x@_ez`Y8!C}Z_sWL^>`BX7=V-l zKAO+z_0TXU$tRT{X)&GXL&MdBY-$bL(Zq$2wDDJea#U11J`ShD5E#qVC%xe?|0kbP z9uAk|QY7X0nB!XbAAfSBB94z=qw~BAH>Jam(uF@cQx*1)U&RTp`ipXicGRvV_@q;# zOAKn5pml*&a16Hmhoz-@36T*0m4=qL6xC30RLQ_T9hPhG!$+a2;e>hgJ&fsc@D!E? z11U}>O{z;J$2rA+WHUJV1?pukIf$Wux7)2A<8b-Zd&fPE$zwk_!G7SVbEx;xj2e4V zj6L9UPZ6I)G7FIbauP%aa~Vdt*)+~6so7;$k9NEH-Of}{cBz-~3!DaHS8&Ih(&X}x1Z5kq!+0p*-4eY!?Ewqd zs!HOWkK`7jV#y4DLwh%mI?@haIsEQ=sZV<~&p^h0Q@pzHwDxL2r!JMAqxX6f*-X18 zGLn#<%zy?=rj>Qa=~d9q%MzysZ=XCfdNI z<)bF7bMd{!R;qTq5=x^b1iss(OUVDqH8j!dke{GQfvN}OZC3R@8a6-Bx{SB-9Cewr zWZdpO_`corzH~d@l?0mLz8KmuO!Eoe_p!^t@4--Bt_>o7p891PM53Q`UW4}~NNT5d zLZ$+KPT zeI!>sDenQjHo!ZLSY|`&McErxqf&X_>m&ku zut z6=Jc^Y|56Fk1CHrVddlnNAA!B;1tQiJB}o|IGH@E1TF3xgV_F;CMQxO9uRW$8wcA( zjOi)-yA*doGj2r7SB`i;Klb2rBkMW)FzYF&z_m!ZujC|(wE6-)99)jn{Cr0aY`V1_ z0%u9nQu9wx_nRL@x43ml(E|z>1V_ZQ}9?>K^JY^*L>#QcXHK-sNBF9y@S% za9`YqzrwEso^BuS(YhF2uHNN?>6z?q#ra&V#j+hS5>M}hb1hYrgtg%Z%(WKOWMT|I zIR!2RzLq@ffv7I^yHF3ms~1%fwY##Ksv0}|(b&b0E7nx~S+S<5wc?^?z^Fu@U|>Eb z{X&ZXgkK|l*wy&P#Q0soZyYZ6+JnVP(PFWBxs52E;uB%PLm=Jb9b4g=CE>A)< zZ>-2v;BQaR!~aU6y6W)+PxI0#O_nGfTR~Pevd@gg_o9p-jWOzoF#}0esi0)AM!a>* zH2S?(?6vg!lt2becW}IrO@g8$dr@|g03WnV2*NzVF5#J|#>;goJZzlMNbNDB$k*E= z8%FL*CPzLXh&fp%N|}nWunkRkMzJm%^(HK(P1%vHC)22f6^UjiEN0YvFziqpy2dgT zhYbdU?b~4zqu+!3V_LIt3aLW3-bzZ%t+$r!m(qzSY~NFW4JmwCp?c{$Oi<{4&>-Xz zThD}(Q+g2!)HrBux4k*4StsBM(tPW9$O3Ubc~lEe#2rV_|4}2<%Tu5$sbRYrjCEv_ z9EDq*dJC70Wo16wMzc8*H810{(9mO=R=rF8ra?BAKk10N%+4G6Y$%@?swMQ-iwL?d zviWA4Ai+VACXJosx=ix$n)6llv1OJ>#BAPZ^OcnuWquO+`gfzyovLGa6#nMw0qnL($BP$DQqt#!SvBctKm+_CF?b{1` z?Zn5Y$qPg;Yxp;Hj&vl$-53lU3lDPlIRMy$i_ z@F(7lIH(8U4}J_WWj}}i{WbW@-=tZ9-U3>hwNv|nh!ezrvbtnph-iz!H3aTyGIv58 zBBP9El9AB0WERCaBQ&-^FrUd1KncS6U?!Vy&3kbwmu$`DTRO6Ns7QDPOm&?(Bh;E; zATDXo@z#!fTQ1cC*Ak3N8WqjAPllis?CdbpGyUA>@4y_yvvMYj$J(>NFO#JwT5&RK zGIs!9zbTK`;+36wd8Wx$v8uQKivHeJVY?|*?@m>OGpz=L)6Z+>uHJC`yqcPHRSoA; zo8*@1)0&M_x2~!P7*dgN1)sYA*IY77a=*llHiI1F&N7!p;#Py*XtWzR0+?qRjZ@;0 zNZgp04LsA-V>I?O8BIomWH6}LZa_$M!ci`11klpPx$!)MY_G1A@lTTIS9b9-6aIy5 zPNz+>7)@@Qi+6L5LX3#0o)!uBtO!?Bgje)bM9N};=AKl4IBg^2*$3^b2D910RqY?Q zuS&t4yf0e z@z2OVppCgjmS@Pg=|P*>Y?BN|eU6@fpM8A?v6zY@N z1M|ABKFJABBHfYjb8?+Qp3z)sBq5TF4Y{y*EbrWZT^t=&6PGv9wl=o^I(ZX8p@U38 zfXB-Q}1vX^P+?u!yf&tzRQvw0X02m(Trk4td1|4NaahN(bEktn{h6 z(PsM^95&Yw3;WV$TP3sxbbg$E(42(pMbJszutGFaWG}A;tu56^jeg8#7wTC-m#09~vi!N&&MwAM~8|X^l$?a#=f~nIX%2hebaw>C8;7`-C^YAE`!r2NtwhznoAXr*N3aa zHh;ixlg^1J;*;jol3J3V3u|4v#oO7HoKxotNafBzu4>AHs_d-7XWkH;{9d~qY`RoF z_fhAIOdq%UYTUSq)#}dgvZA=}sD(3uvy>QNqUiC@dWc-BX>5#wE$; zG`PySp*h|Zkff-)F4#0#o0*Z^l({o1LZLA-)BZPk2)68Wh<`6JqdijRag|E}ce+2; z+~~^2+~r*AZKB4no|21HMk-JNZS_Wpu9!xI#*q|-Tw1dU1=6%R2_9Nf#Z*ZZWvZdp z4%8Z{_CDSQ^%vcB_`2f{vy$|MEg-bC>TcEyto!9|Qm54wTG_!-G z+ZhfXQGb+R4cxQ1Uju|$EleJmjMZfAV4(@C8 z|DYYAUGpOyj-tXxM5wf95~GgCpgDn%UHF8M0r0H8GY0pG^c4R1$hsV?7uvW~Pplf* z!kD}?ZL_-3s*;auuF1lx2DyN6gV|~fQiUN9(3<#OLV7O@pQU|TP3u<>(&87K7OY2iy_8ATGV~{hf)-6(%&PA`3&Jh=O+M_m`ZA;;O znkLfO{6D$P>~;PG=PGSms2)$1p3s=Bu0KtcCXv4L1z3G|g0lHQ={u zBiApHv((%w+@-=4hWf~T$wz?+@Dbsqe?P>mP>kcU)WlxQ5<|Z2l*VZ`LI_ zuQ<2>ZDZmE%73E5*H6$pyaZ7%dp-Oj`^ACp7<6d6&$=H$n`t z*`xImvk`Wa)?_x#F}gfP=p&u^w5LTr3yvL44Us<4)R0rv&t#j+ZB_qE`cA>co8yg* zabAa|-8J#THM#A&JU{?EdF)KtLXXY!Mf<>Oc>Hw!ig>cu9h z9V)HxnM2c#Np1R}X06gA2FMWTL$H^A*j}_Q(6JQT;cf0{N&9@>9h®9K?4Tre1; zBfh-v+x_Bn?Mb!eK419`vZn3mQES%G&Ff&(QFh>bx~09vyF-frs2p50rzaMRJqUw} zI-K`p-{n=NnYXvQsc(En|9<2t&TerOmFJ>RX>%}uR~z8^NjfC?f05CU)d+SM&b6B`(KWz$7Fxx$8Ph{CbRt; z{Oc}92a;iRpd8MDT* zi6)T+#_T71x~3ctE7R>6W6qzFzpGyD@ARuz+qo6gop0e=K+CQCbeI2H49cr9YOmE9 zku-_8ih9b`SM#6qby%vcZpRZg$;#KOw^${cJ$f!!_D6fgfZq$|O5(^z;*gH!?4`aY z{Qs)OgV?dMwvp&5rc6sKO`Mii@|TjrPvOEOl4ZR#7N8&H6A(UIeJ1(rf?L{KaEsSU zdr2>?-v0}l^>P<}rG150rRLc*pKQQ*>CoJjEi!1E)E%mlzUks()HqSS!WotO)4fq~@*cb4o z!dAKZn}~}1G#EF;pAJ=2gr3Gub94Fjx4qRdw{7iOo4YdYeS3R3d~W)9qw;HLB_yYq z$T$WRrYQD=1(u?V$nTWz1Ph~4hrj$6At|bnl31DHWZCjjnbCBg5!!y4*&x3vTL1>L zrIs7-Ga1W1vdAYJ%0h>zj9b(>B<(AE*DR$ZxA{jV^FPd1X|sesD|SskGP`lX{BGIo zFQ{;{XcE2NPsx`ejw4K~n9=ee_T<9n9@IY&)Z!*Rm|HNP`aM}s1|EK`=jC&)wc*0u z6*WGq2VrE^3v4cv*=pze%B>63g0+KN)ek8=e7VISy&Q@}np?c;Kh=LZZI@VKBQuoS z_*LBKZE>r6ZBBL9B!rh)dAS+atRrM(AFI;vDv^=FD0SWmiX+_ihs7~ZRrk@D4IV@Fn;Z)HTh~mmW4Kl(Nw=tbQU1{;FOsaFY6a z#m=;nnvG%p6AGs13rV6vY}7Z3%vNjv-^jaR1M0+T@M*NdIGxC+VS(}@E;|i*1+7O|FeLWyurS|DG@N{eo&%Xugc0DAlzZ9@q|M8g5q-h$`rczJEGA!5jd*Cm+S5;{Y4VvY7034W zO(*8kfyZhFk0W8vHC>X$b4Q&i%bP)KG?@)?_Y&kKvb@1_ks>=McuGlgW37tjb^@<4 z`?DQcU9`{?bci1Er-=9|yAbB#nK6>%V$$QW+ViY-huyhg{gDo9;WDe!X_d~iI;6=~ zsJ3Dj`7Dow=Pxt=}x|9 zDH(=uu;H&#leMs-4!rNHkag-IJsg2m=No7>GWjs1weMf#B>S9fQh4h^# zyD&x|dKX?EM4M{jr&090I3$AxI5vV{;R(`s8qCXCJW6je;c7j4KpRGQgI}H%OE*N5 zTsm{8tF9WqBss6saxuY3kYMM4)F9Id>J#FLT zRd$Q|vBef@?C$S|^cO7mhht67U@RT;@P#(ZCmCCL5SJQ5{Fay}SexskqN)>Z@q~27 zvc6nx$P=qt-1I#vtg@m#^S!3Ue5Kdx6>rzdy11eR1!tPu1sa9FS!_1T_o})ZgTbH_ z=!!q=wz*rY!fsE@qdsr3T|A>Z=m~~^P!)!wM(1|RPh&ncK@S&n4sD!8^lml{fd_4b z#>W|75VVV$9}@`e9n|R^CQ>mt1$>j5RGVN2>0DEG!2dC%eD3c~_Ai#C#r^m-sQaRG z>X&Siq)kiOmPGzWXP0pNR@K)J)YljGb@e*;#!|6Q(^=eu1HF()R{baG;kIK)y9ZnruD` z(b=47mN2#@lQ~NZ#e$H*psGuOpcz9C!zWK(zqWn}%>c>+-(4s6F;jiGk8U^n#gh_Z z14tCdz|~$X!GIw_V!}uZLS&Z^EI^_iMj>8|-Lz<4tvRcLE_tnLwz_;fgydJ$*1NSLrwtMim;$(s3lqTic;_Ie=azL}OwWZp8qa%DegU+xo3bX*JOisUo1j0F zc&@tzfG7Oc&2$wk1xNV99hwUqqZF$Sv~w~RJz#C1aC_&1Z5Yw?8n7GUqW#1oX-9h% zemcaeq1Mivh}%KL?G3?!T1O&PSKi<<#v%cm)#mVaM1r|+Jn7(OTQE}XvODU#!*wp7 zRWeRa&R?_s%{4QQ4}{$Fe9QV9jyrBe-4VTxsNXD^GRcalNtUe6kSAo3{E<*T8SM;7 z@h-pHVwS8XM_dZp%cL@=EA6tFtZsY25;vQqchY^5E!h&C-V9$~(B_N>Dknz+jpYGE zaT=|`NX%%c@nl@Sj4RUnSRT>B{#h>?aKa!na#nh#TRfIET&8dk=FU%UeYx&jt>5o^-U^2NyboUI9^W5B6`WVJ4b1Kj|Ghd(qRy%`@1+~m zXPWzZFX`<&E{yjz|2?&0&2pVb?1GJ_3z>N+I)ibc!=wJ0Y8r0Z%F!TdQjO7*qc{uj zjy7%BX>4^ejM&jcpvxk^?An5n`L0qXZf-M1@h6|1a>yAtof@P{BCvWfO5#Rkr zkL@Y-W3$cXjYi=zGji+8{xYN6YH}vMf%067$pXi}(?}*Y^;^fTT)Ma`T{EzF(TZiH zT^ePZEEye5Hirqq0le#1uJrpQQ@KCFtxm_24pW7H|9k!lZgzj@;r^!ODSsy5YFM7C z51Y-faR>dbtK7c7nQE&08q(4|RkgWT0zne;UkqleY;bsz6@AT(C$~GxG3Xw+Y^u&% zAVci|y&1M4^29+k&8QiV$W(-Y&XWDK9z<4Lc4?Mx*UX1*&6K$RQAv|1HB+Kfw;qux zQTj6llpVKHTY-3v&H8WK5P|Df>Aw+Yn1l?#cn9bnge8+%Ho>H&**Ei^_O#|=>&T|^ ziJ%b?w^~qC&XbV8w8`LesND{q;be)YDx}TuysK~Uy6JWN#RdG@MTOmWl+Qs-MACD6 z;eP%U#2CBFX;iaVqwy(`+=kL{T}O`R7>rz8BKX*)0%2iN2y zk^GuL^(plp&X-@a7&P6!*i#vd$AeCI@U#qa2i}wK1iq7DJ6Vb>NGBtL=>kMAU54x} zw;*=u2gqRaFwGo)s)PRL@E==0%v~DLz6O3=!5O+PuF-wkxsH^vct2gG`|%6SEalad zF_3=EtQI51%%8>iw0=y=8Z7~X$*m(u_v`10XqBEX-cRRArY_zuZ|GlfOAi0;Ufbm}1Zhe2QKf7+bdQE?S_x4Z~=T#xGiCwdPU_iQa z_*^0pyQZeUf5Ye#>gdO^0|Wfy_3PJV+v(MtmlF!Pf%f)w>)LDj*Y#&}z~OEbpX<*p zAGoC-$tH?LQptVSpxnDhpUMuXo3(R^gnm;^zqqO71of#F`y<~e{RVTRO3U!sLw3zf zibMxQc4@&hP=$!DijG2Dft@p7Du^y6ULyOuP@IL zIcxL2R$e$KQC~l`zCIxx@tS0is;~@dMCT$$QHs3BUS6@JI^(zsz{#9(GlQ}&#vw0mo z<*|QzyqZiaZ-YTYz5T@sKIPZgQ2RsI2W@&rdKdHmXiXPwk~%0Z57J93so*Ya0BVLotk=zB{q}Bgt(i@sR7(yxj3-rxkxwOiXv{yge zD|!{>J9s1mQ~rYE^Gl{@BECSfw>8Y;;g+g_`Hg&M+flR9{8lbyBlX$lBeIPZDPyR) zCs|hJjrGiHnBNyq&0N+xv)JyU+yUYUhb}owW8SYtp>$}P3+4owk9~)M(yy&C>kL0E zQ`5<0a0!ksu^k#sm(4c)bFvD3K7$0HORRVbNd?515x7$%&0*jU`GXuOn7(mX0ibeK zV)l~ab?Dao^~E+|OXbh-#r!j@uyGu+eR~9|e(Q{b=wq0d^z{nLFLyYY8#BN+pCgSD zd-;w&cnHWBRh$)?b_oZCwgNW^?vNf;#o?+SMqT$mZ^J4|PcVZtx#non>vGgr_+xE- zwX-IB9u7R#lg zzGP*0vN9Qm#ZvY+hEqLlVSim{`@t53(@$?ztr`CxYRi7KEC@Rp>pTv>CIHIAYe!)8bXl*_i`pS6aii%CiS%W}Ej_ z&RI04J09;A8)S@{(v3l*IMRQK@na#cv<}6yYcJ++ERK{YH z<{UX^lGtc6q`=*c94Eb$eUnlIkvqCig1s1m?y$j1sLfwc6|5MfYLa$Mla1751ZV|g zlEi9DknNsRdziJHU6bn1t*NS7lj~2_v>wylJ224Oy}U*GX0Z<4gH#puAv9Un97(i6 z;tQ%j^T?%h=1y7~3@)8Cch0gSJ60bNz`rBb=(Ob-=|$vD7V(fp{%=GpP<^VXaxxs5 zF^PC-6-Wq{=fj9M+&&VkgDIt_hu>oJ#{J!k)~fs09y!TR@!R5<8}ws!^57cI*9^`f zD-8c5?;#sZ&pKnOaZ+?vZChLItmvf1lyUU&{l!P-46eca6>%7Za|+pY2PxAknfND0 zmIPW_Cqhde1l}Nn!n#pvR)g_hm~rH%4^@#tLn6YPr!D

9po(mC;xgZJxI5gC)~i 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

R0AMv>n9kBSrZWQv zj8gze2D43>%1lq=EoEYKXnJNcW0)Apj%Q300}~mniO~t`cy@Yp@8}R8Su?eG2E#oz zY#1FM%pQ@b);e`ybSzV&eM06J7y%kZ ze0N}M2;9eXc2XW1p(e}wMyE$+1|2yr1@mz~0B`3wNBcx}Wl4Gh8cbcvLHEh*B$Sh*B@x=+zqSq9$vZnV2gBzYHA3 z3K=-6gGafR<8>4Jv@cE!@8tzE;i`;&Z(^DkEHmT# z$Fqld*>pHN$y<~*4rATWe{-%-lT{962dRO|^Z;-;eq|7Cm_mgqaH&|()5hTeJQ|qF zC^U>%Hl~s6%;dhYfvG8Rf99yPcWhuE7W>ic%(Mc;K{Hd_vbk59+CMrjO=q)XB4&{l zy{5&zZxZteeVd%5`eto9(*wtRk=GFq42+ATQ-`E|qkE_2(P6wYY&igwIRq?&b!-Lt z#45{-0en-^BoL&$d0=m5`lx((U<~~*9M0kkG#2!A;L-8@a{pv@V&tfi7BXOv&J`LA zW25^s4FJv*FYrr(6~6>PX2u57$|R;Xz=M$*15ncPzy#1`TH&XftZ`s`crrUWj2l|P zJ}@?Vcwl@V{jbTUEqRx~&`0%knYPWBQOh`yJ)D`$?%iveo*Wp?92l6~FYN`IFww|! zoNSoN&WsNmXq}Hphk@p#siWgVSbzIQ$7LL85GDbXf#Ece_0-hBzD(Kx%(*`!_H0;b zMr%QZCNnizQ?7`|Lj&V!nnaliqB59z*g^~pO;4GovSTy+mV`C6Um}7F>t&6k5IU~W@Ue-PX$_dL*#X8G-8XInmzOjr9qJ1n2en@-h*gG(U36b5ezocLsCNM$FT5Vzj97L$l_}of% z&^($sP;($Vp4~S&aDcGi*uY@!HZ2zdy|8hkVQT-;iHvP}AUima)qfz@Ms3|IG>>Nn zGxA|Vh11G3mN`~{;c#YjFe~--uU(USTdQy75A+`C7g}#EOVOdtm_BH{3^*K}88;jo z86BBX1~VgI5;Ml($X^j< literal 0 HcmV?d00001 diff --git a/features/app-core/fonts/registry.tsx b/features/app-core/fonts/registry.tsx new file mode 100644 index 00000000..4a7f3d8c --- /dev/null +++ b/features/app-core/fonts/registry.tsx @@ -0,0 +1,38 @@ +// import { +// Roboto_100Thin, +// Roboto_300Light, +// Roboto_400Regular, +// Roboto_500Medium, +// Roboto_700Bold, +// Roboto_900Black, +// } from '@expo-google-fonts/roboto' + +/** --- fontPaths ------------------------------------------------------------------------------ */ +/** -i- Register any font paths for web preloading */ +export const fontPaths = { + // - Google Fonts - + Roboto100: '@expo-google-fonts/roboto/Roboto_100Thin.ttf', + Roboto200: '@expo-google-fonts/roboto/Roboto_300Light.ttf', // Fallback + Roboto300: '@expo-google-fonts/roboto/Roboto_300Light.ttf', + Roboto400: '@expo-google-fonts/roboto/Roboto_400Regular.ttf', + Roboto500: '@expo-google-fonts/roboto/Roboto_500Medium.ttf', + Roboto600: '@expo-google-fonts/roboto/Roboto_700Bold.ttf', // Fallback + Roboto700: '@expo-google-fonts/roboto/Roboto_700Bold.ttf', + Roboto800: '@expo-google-fonts/roboto/Roboto_900Black.ttf', // Fallback + Roboto900: '@expo-google-fonts/roboto/Roboto_900Black.ttf', + // - Icon Fonts - + AntDesign: '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf', +} + +/** --- fontRegistry --------------------------------------------------------------------------- */ +/** -i- Register any font for mobile preloading */ +export const fontRegistry = { + // - Google Fonts - + Roboto: require(fontPaths.Roboto400), + RobotoLight: require(fontPaths.Roboto300), + RobotoRegular: require(fontPaths.Roboto400), + RobotoBold: require(fontPaths.Roboto700), + RobotoBlack: require(fontPaths.Roboto900), + // - Icon Fonts - + AntDesign: require('@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf'), +} diff --git a/features/app-core/fonts/registry.web.tsx b/features/app-core/fonts/registry.web.tsx new file mode 100644 index 00000000..4e03a9bf --- /dev/null +++ b/features/app-core/fonts/registry.web.tsx @@ -0,0 +1,49 @@ +import { Roboto as RobotoGoogleFont } from 'next/font/google' +import localFont from 'next/font/local' + +/** --- fontPaths ------------------------------------------------------------------------------ */ +/** -i- Register any font paths for web preloading */ +// export const fontPaths = { +// // - Google Fonts - +// Roboto100: '@expo-google-fonts/roboto/Roboto_100Thin.ttf', +// Roboto200: '@expo-google-fonts/roboto/Roboto_300Light.ttf', // Fallback +// Roboto300: '@expo-google-fonts/roboto/Roboto_300Light.ttf', +// Roboto400: '@expo-google-fonts/roboto/Roboto_400Regular.ttf', +// Roboto500: '@expo-google-fonts/roboto/Roboto_500Medium.ttf', +// Roboto600: '@expo-google-fonts/roboto/Roboto_700Bold.ttf', // Fallback +// Roboto700: '@expo-google-fonts/roboto/Roboto_700Bold.ttf', +// Roboto800: '@expo-google-fonts/roboto/Roboto_900Black.ttf', // Fallback +// Roboto900: '@expo-google-fonts/roboto/Roboto_900Black.ttf', +// // - Icon Fonts - +// AntDesign: '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf', +// } + +// const Roboto = localFont({ src: '@expo-google-fonts/roboto/Roboto_400Regular.ttf' }) +// const RobotoLight = localFont({ src: '@expo-google-fonts/roboto/Roboto_300Light.ttf' }) +// const RobotoRegular = localFont({ src: '@expo-google-fonts/roboto/Roboto_400Regular.ttf' }) +// const RobotoBold = localFont({ src: '@expo-google-fonts/roboto/Roboto_700Bold.ttf' }) +// const RobotoBlack = localFont({ src: '@expo-google-fonts/roboto/Roboto_900Black.ttf' }) +// const AntDesign = localFont({ +// src: '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf', +// }) + +const Roboto = RobotoGoogleFont({ weight: '400', subsets: ['latin'] }) +const RobotoLight = RobotoGoogleFont({ weight: '300', subsets: ['latin'] }) +const RobotoRegular = RobotoGoogleFont({ weight: '400', subsets: ['latin'] }) +const RobotoBold = RobotoGoogleFont({ weight: '700', subsets: ['latin'] }) +const RobotoBlack = RobotoGoogleFont({ weight: '900', subsets: ['latin'] }) + +const AntDesign = localFont({ src: './AntDesign.ttf' }) + +/** --- fontRegistry --------------------------------------------------------------------------- */ +/** -i- Register any font for mobile preloading */ +export const fontRegistry = { + // - Google Fonts - + Roboto, + RobotoLight, + RobotoRegular, + RobotoBold, + RobotoBlack, + // - Icon Fonts - + AntDesign, +} diff --git a/features/app-core/hooks/useLoadFonts.ts b/features/app-core/hooks/useLoadFonts.ts index 01c95ec3..cc13b7c0 100644 --- a/features/app-core/hooks/useLoadFonts.ts +++ b/features/app-core/hooks/useLoadFonts.ts @@ -1,46 +1,60 @@ 'use client' import { useFonts } from 'expo-font' -import { - Roboto_100Thin, - Roboto_300Light, - Roboto_400Regular, - Roboto_500Medium, - Roboto_700Bold, - Roboto_900Black, -} from '@expo-google-fonts/roboto' +// import { +// Roboto_100Thin, +// Roboto_300Light, +// Roboto_400Regular, +// Roboto_500Medium, +// Roboto_700Bold, +// Roboto_900Black, +// } from '@expo-google-fonts/roboto' +import { REGISTERED_FONTS } from 'registries/fonts.generated' /* --- useLoadFonts() -------------------------------------------------------------------------- */ const useLoadFonts = () => { - const fontsToLoad = { - // - Google Fonts - - Roboto: Roboto_400Regular, - RobotoLight: Roboto_300Light, - RobotoRegular: Roboto_400Regular, - RobotoBold: Roboto_700Bold, - RobotoBlack: Roboto_900Black, - Roboto100: Roboto_100Thin, - Roboto200: Roboto_300Light, // Fallback - Roboto300: Roboto_300Light, - Roboto400: Roboto_400Regular, - Roboto500: Roboto_500Medium, - Roboto600: Roboto_700Bold, // Fallback - Roboto700: Roboto_700Bold, - Roboto800: Roboto_900Black, // Fallback - Roboto900: Roboto_900Black, - // - Icon Fonts - - AntDesign: require('@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf'), - } - - const [googleFontsLoaded, googleFontsError] = useFonts(fontsToLoad) - - if (googleFontsError) console.error('googleFontsError:', googleFontsError) + // Hooks + const [fontsLoaded, fontsError] = useFonts(REGISTERED_FONTS) + + // -- Debug -- + + if (fontsError) console.error('fontsError:', fontsError) // -- Return -- - return googleFontsLoaded + return fontsLoaded } +// const useLoadFonts = () => { +// const fontsToLoad = { +// // - Google Fonts - +// Roboto: Roboto_400Regular, +// RobotoLight: Roboto_300Light, +// RobotoRegular: Roboto_400Regular, +// RobotoBold: Roboto_700Bold, +// RobotoBlack: Roboto_900Black, +// Roboto100: Roboto_100Thin, +// Roboto200: Roboto_300Light, // Fallback +// Roboto300: Roboto_300Light, +// Roboto400: Roboto_400Regular, +// Roboto500: Roboto_500Medium, +// Roboto600: Roboto_700Bold, // Fallback +// Roboto700: Roboto_700Bold, +// Roboto800: Roboto_900Black, // Fallback +// Roboto900: Roboto_900Black, +// // - Icon Fonts - +// AntDesign: require('@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf'), +// } + +// const [fontsLoaded, fontsError] = useFonts(fontsToLoad) + +// if (fontsError) console.error('fontsError:', fontsError) + +// // -- Return -- + +// return fontsLoaded +// } + /* --- Exports --------------------------------------------------------------------------------- */ export default useLoadFonts diff --git a/features/app-core/tailwind.config.js b/features/app-core/tailwind.config.js index 77dcc744..69c4aed6 100644 --- a/features/app-core/tailwind.config.js +++ b/features/app-core/tailwind.config.js @@ -33,22 +33,23 @@ module.exports = { /* --- Intellisense Setup ---------------------------------------------------------------------- */ // Enable intellisense by installing the "Tailwind CSS Intellisense" vscode plugin // Also add the following to your vscode's .settings file to get the addon to work properly: -// -- -// "tailwindCSS.classAttributes": [ -// "class", -// "className", -// "tw", -// "tailwind", -// "style" -// ], -// "tailwindCSS.experimental.classRegex": [ -// "tw`([^`]*)", // tw`...` -// "tw=\"([^\"]*)", //

-// "tw={\"([^\"}]*)", //
-// "tw\\.\\w+`([^`]*)", // tw.xxx`...` -// "tw\\(.*?\\)`([^`]*)" // tw(Component)`...` -// ], -// "tailwindCSS.includeLanguages": { -// "typescript": "javascript", -// "typescriptreact": "javascript" -// }, +/* -- + "tailwindCSS.classAttributes": [ + "class", + "className", + "tw", + "tailwind", + "style" + ], + "tailwindCSS.experimental.classRegex": [ + "tw`([^`]*)", // tw`...` + "tw=\"([^\"]*)", //
+ "tw={\"([^\"}]*)", //
+ "tw\\.\\w+`([^`]*)", // tw.xxx`...` + "tw\\(.*?\\)`([^`]*)" // tw(Component)`...` + ], + "tailwindCSS.includeLanguages": { + "typescript": "javascript", + "typescriptreact": "javascript" + }, +-- */ diff --git a/packages/@registries/fonts.generated.ts b/packages/@registries/fonts.generated.ts new file mode 100644 index 00000000..63ceb3ce --- /dev/null +++ b/packages/@registries/fonts.generated.ts @@ -0,0 +1,8 @@ +// -i- Auto generated with 'yarn ats collect-assets' +import { fontRegistry } from '../../features/app-core/fonts/registry' + +/* --- Exports --------------------------------------------------------------------------------- */ + +export const REGISTERED_FONTS = { + ...fontRegistry, +} // prettier-ignore From a5bdf0a25281cf4a79b918bfafe935e9915791d3 Mon Sep 17 00:00:00 2001 From: codinsonn Date: Mon, 26 Jun 2023 19:43:48 +0200 Subject: [PATCH 2/2] wip: Attempt to transpile packages with SWC as Expo docs suggest --- apps/next/next.config.js | 102 ++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/apps/next/next.config.js b/apps/next/next.config.js index 417bf6b7..09bf61b2 100644 --- a/apps/next/next.config.js +++ b/apps/next/next.config.js @@ -1,12 +1,12 @@ // -i- Based on: https://github.com/axeldelafosse/expo-next-monorepo-example/blob/main/packages/next/next.config.js const { withExpo } = require('@expo/next-adapter') -const withFonts = require('next-fonts') -const withImages = require('next-images') +// const withFonts = require('next-fonts') +// const withImages = require('next-images') /* --- Transpiled Modules ---------------------------------------------------------------------- */ const transpiledModules = require('config/transpiledModules') -const withTM = require('next-transpile-modules')(transpiledModules) +// const withTM = require('next-transpile-modules')(transpiledModules) /* --- Automation Scripts ---------------------------------------------------------------------- */ // -i- This will run the aetherspace automation scripts on local dev builds (comment out what you don't need) @@ -37,20 +37,20 @@ const withAutomation = () => { /* --- PWA Config ------------------------------------------------------------------------------ */ -const withPWA = require('next-pwa')({ - // https://github.com/shadowwalker/next-pwa#available-options - dest: 'public', - disable: process.env.NODE_ENV === 'development', - // -i- Enable these to make the app a full PWA with service worker - // register: true, - // scope: '/app', - // sw: 'service-worker.js', -}) +// const withPWA = require('next-pwa')({ +// // https://github.com/shadowwalker/next-pwa#available-options +// dest: 'public', +// disable: process.env.NODE_ENV === 'development', +// // -i- Enable these to make the app a full PWA with service worker +// // register: true, +// // scope: '/app', +// // sw: 'service-worker.js', +// }) /* --- Build Next Config ----------------------------------------------------------------------- */ -const projectRoot = __dirname -const workspaceRoot = `${projectRoot}/../..` +// const projectRoot = __dirname +// const workspaceRoot = `${projectRoot}/../..` // -i- Next specific config, e.g. https://nextjs.org/docs/api-reference/next.config.js/introduction /** @type {import('next').NextConfig} */ @@ -58,48 +58,52 @@ const nextConfig = { typescript: { ignoreBuildErrors: true, }, - images: { - domains: ['i3.ytimg.com'], - }, - webpack: (config, { isServer }) => { - // -i- Run aetherspace automation scripts in DEV mode - if (!isServer && process.env.NODE_ENV === 'development') withAutomation() - // Enable top level await in API handlers - config.experiments.topLevelAwait = true - // Silence warnings about "unexpected" resolutions (file-loader) - config.infrastructureLogging = { level: "error" } - // Aliases for web support (https://github.com/expo/expo/issues/21469#issuecomment-1576001543) - config.resolve.alias['expo-asset'] = 'expo-asset-web' - // Return config - return config - }, + // images: { + // domains: ['i3.ytimg.com'], + // }, + // webpack: (config, { isServer }) => { + // // -i- Run aetherspace automation scripts in DEV mode + // if (!isServer && process.env.NODE_ENV === 'development') withAutomation() + // // Enable top level await in API handlers + // config.experiments.topLevelAwait = true + // // Silence warnings about "unexpected" resolutions (file-loader) + // config.infrastructureLogging = { level: "error" } + // // Aliases for web support (https://github.com/expo/expo/issues/21469#issuecomment-1576001543) + // config.resolve.alias['expo-asset'] = 'expo-asset-web' + // // Return config + // return config + // }, // App dir support reactStrictMode: true, + transpilePackages: transpiledModules, experimental: { - // appDir: true, - // transpilePackages: transpiledModules, forceSwcTransforms: true, }, } -// Apply plugins to next config, avoiding next-compose-plugins: -// -i- https://github.com/cyrilwanner/next-compose-plugins/issues/59#issuecomment-1209152211 -// -i- https://github.com/cyrilwanner/next-compose-plugins/issues/59#issuecomment-1220739666 -const plugins = [withTM, withFonts, withImages, withPWA, [withExpo, { projectRoot: workspaceRoot }]] -const withPlugins = (_phase /*, { defaultConfig } */) => { - // Build final config - const finalConfig = plugins.reduce( - (acc, plugin) => { - // Handle plugins with options - if (Array.isArray(plugin)) return { ...acc, ...plugin[0](acc, plugin[1]) } - // Handle plugins without options - return { ...acc, ...plugin(acc) } - }, - { ...nextConfig } - ) - // Return final config - return finalConfig; -} +const withPlugins = withExpo({ + ...nextConfig, + // experimental: {}, +}) + +// // Apply plugins to next config, avoiding next-compose-plugins: +// // -i- https://github.com/cyrilwanner/next-compose-plugins/issues/59#issuecomment-1209152211 +// // -i- https://github.com/cyrilwanner/next-compose-plugins/issues/59#issuecomment-1220739666 +// const plugins = [withTM, withFonts, withImages, withPWA, [withExpo, { projectRoot: workspaceRoot }]] +// const withPlugins = (_phase /*, { defaultConfig } */) => { +// // Build final config +// const finalConfig = plugins.reduce( +// (acc, plugin) => { +// // Handle plugins with options +// if (Array.isArray(plugin)) return { ...acc, ...plugin[0](acc, plugin[1]) } +// // Handle plugins without options +// return { ...acc, ...plugin(acc) } +// }, +// { ...nextConfig } +// ) +// // Return final config +// return finalConfig; +// } /* --- Exports --------------------------------------------------------------------------------- */