From c8168c70345dd935712d816effc358d8c275f88c Mon Sep 17 00:00:00 2001 From: Salute Frontend Team Date: Fri, 10 May 2024 08:51:08 +0000 Subject: [PATCH] Update package-lock.json files --- .../plasma-web Slider -- _disabled.snap.png | Bin 0 -> 4084 bytes .../plasma-web Slider -- _placement.snap.png | Bin 0 -> 16563 bytes .../plasma-web Slider -- _size.snap.png | Bin 0 -> 4799 bytes .../plasma-web Slider -- _view.snap.png | Bin 0 -> 6411 bytes .../plasma-web Slider -- simple.snap.png | Bin 0 -> 6608 bytes .../plasma-web Slider -- _disabled.snap.png | Bin 0 -> 3818 bytes .../plasma-web Slider -- _placement.snap.png | Bin 0 -> 15923 bytes .../plasma-web Slider -- _size.snap.png | Bin 0 -> 4493 bytes .../plasma-web Slider -- _view.snap.png | Bin 0 -> 6124 bytes .../plasma-web Slider -- simple.snap.png | Bin 0 -> 6166 bytes packages/plasma-b2c/api/plasma-b2c.api.md | 32 +- .../Slider/Slider.component-test.tsx | 2 +- .../src/components/Slider/Slider.config.ts | 241 +++++++++++++ .../src/components/Slider/Slider.stories.tsx | 114 ++++-- .../src/components/Slider/Slider.tsx | 28 +- .../plasma-b2c/src/components/Slider/index.ts | 2 +- .../src/components/Slider/Slider.tokens.ts | 88 +++++ .../src/components/Slider/Slider.tsx | 51 +++ .../src/components/Slider/Slider.types.ts | 3 + .../Slider/components/Double/Double.styles.ts | 75 ++++ .../Slider/components/Double/Double.tsx | 328 ++++++++++++++++++ .../Slider/components/Double/Double.types.ts | 70 ++++ .../Slider/components/Single/Single.styles.ts | 92 +++++ .../Slider/components/Single/Single.tsx | 183 ++++++++++ .../Slider/components/Single/Single.types.ts | 60 ++++ .../SliderBase/SliderBase.styles.ts | 36 ++ .../components/SliderBase/SliderBase.tsx | 87 +++++ .../components/SliderBase/SliderBase.types.ts | 48 +++ .../src/components/Slider/components/index.ts | 6 + .../src/components/Slider/index.ts | 7 + .../Slider/ui/Handle/Handle.styles.ts | 28 ++ .../components/Slider/ui/Handle/Handle.tsx | 185 ++++++++++ .../Slider/ui/Handle/Handle.types.ts | 24 ++ .../Slider/ui/Thumb/Thumb.styles.ts | 47 +++ .../src/components/Slider/ui/Thumb/Thumb.tsx | 19 + .../components/Slider/ui/Thumb/Thumb.types.ts | 11 + .../src/components/Slider/ui/index.ts | 7 + .../src/components/Slider/utils/index.ts | 58 ++++ .../Slider/variations/_disabled/base.tsx | 3 + .../Slider/variations/_disabled/tokens.json | 4 + .../Slider/variations/_size/base.tsx | 3 + .../Slider/variations/_size/tokens.json | 0 .../Slider/variations/_view/base.tsx | 3 + .../Slider/variations/_view/tokens.json | 0 .../src/components/TextField/TextField.tsx | 14 +- .../plasma-new-hope/src/engines/common.tsx | 19 +- packages/plasma-new-hope/src/engines/index.ts | 2 +- packages/plasma-new-hope/src/engines/types.ts | 6 + .../components/Slider/Slider.config.ts | 243 +++++++++++++ .../components/Slider/Slider.stories.tsx | 150 ++++++++ .../plasma_b2c/components/Slider/Slider.ts | 12 + .../components/Slider/Slider.config.ts | 243 +++++++++++++ .../components/Slider/Slider.stories.tsx | 150 ++++++++ .../plasma_web/components/Slider/Slider.ts | 12 + packages/plasma-new-hope/src/hooks/index.ts | 1 + .../src/hooks/useIsomorphicLayoutEffect.ts | 8 + packages/plasma-new-hope/src/index.ts | 1 + .../plasma-new-hope/src/utils/canUseDOM.ts | 9 + packages/plasma-new-hope/src/utils/index.ts | 1 + packages/plasma-web/api/plasma-web.api.md | 32 +- .../Slider/Slider.component-test.tsx | 97 +++++- .../src/components/Slider/Slider.config.ts | 241 +++++++++++++ .../src/components/Slider/Slider.stories.tsx | 92 ++++- .../src/components/Slider/Slider.tsx | 28 +- .../plasma-web/src/components/Slider/index.ts | 2 +- packages/sdds-serv/api/sdds-serv.api.md | 10 +- 66 files changed, 3221 insertions(+), 97 deletions(-) create mode 100644 cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png create mode 100644 cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _placement.snap.png create mode 100644 cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _size.snap.png create mode 100644 cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _view.snap.png create mode 100644 cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- simple.snap.png create mode 100644 cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png create mode 100644 cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _placement.snap.png create mode 100644 cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _size.snap.png create mode 100644 cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _view.snap.png create mode 100644 cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- simple.snap.png create mode 100644 packages/plasma-b2c/src/components/Slider/Slider.config.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/Slider.tokens.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/Slider.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/Slider.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Double/Double.styles.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Double/Double.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Double/Double.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Single/Single.styles.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Single/Single.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/components/Single/Single.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.styles.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/components/index.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/index.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.styles.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.styles.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.types.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/ui/index.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/utils/index.ts create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_disabled/base.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_disabled/tokens.json create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_size/base.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_size/tokens.json create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_view/base.tsx create mode 100644 packages/plasma-new-hope/src/components/Slider/variations/_view/tokens.json create mode 100644 packages/plasma-new-hope/src/examples/plasma_b2c/components/Slider/Slider.config.ts create mode 100644 packages/plasma-new-hope/src/examples/plasma_b2c/components/Slider/Slider.stories.tsx create mode 100644 packages/plasma-new-hope/src/examples/plasma_b2c/components/Slider/Slider.ts create mode 100644 packages/plasma-new-hope/src/examples/plasma_web/components/Slider/Slider.config.ts create mode 100644 packages/plasma-new-hope/src/examples/plasma_web/components/Slider/Slider.stories.tsx create mode 100644 packages/plasma-new-hope/src/examples/plasma_web/components/Slider/Slider.ts create mode 100644 packages/plasma-new-hope/src/hooks/useIsomorphicLayoutEffect.ts create mode 100644 packages/plasma-new-hope/src/utils/canUseDOM.ts mode change 120000 => 100644 packages/plasma-web/src/components/Slider/Slider.component-test.tsx create mode 100644 packages/plasma-web/src/components/Slider/Slider.config.ts diff --git a/cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png b/cypress/snapshots/b2c/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ac2f0d5f1d2ebddae2e9301f3f0718d21bbfe8 GIT binary patch literal 4084 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 i62{#P}%6?GhEhuvZ71Er;bEunww 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 G;y(dEF{I)E literal 0 HcmV?d00001 diff --git a/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png b/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _disabled.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..910823a0e1a4338172f4935ee46de603e0cf21df GIT binary patch literal 3818 zcmeHK|5KXx9e&TXI>>sBM%wqe#7kl3b)ttzS?? zZoBF&c9LcBOGU-*i%wi{6AKkky1JA`6x=w&5h}zG#Ha{Dq9Wh+esKGx>+bdkc=!06 zK75|f`~7}>`^c}}%)1bQ`yLKKkcf*vJ$D&FFwfDSBZuIL`l0z2f<*rH;<+CcHel?3 zEAJp2{^ZcY*n5D$B@- zsBtZL>_oYGl4I*z_QrC)%9_kLgshHYk%=M<@@N!6>=cB%9gmQk3b;HCNy}}Zgqy+l?9D%sKy`8;nU`$R;&F5$P@3IEmy8LYG z-d=_-HEeYlJ8?!^!wGn7e_ro>Eq~zYjxyLR5{Xe~c$gDwRFGR*l{z9UrO|8~@C38>C*x~YjzyNv2Y@qyB3P4ZY`gZRfY-hkIpBT2|Hbpw*V#t$t$qobp~ zJ8_lE>tjldp4RdTtnt_cZ)j_P|I}PoEU;k6$CGF6q8I*oIrs=!Wxa zwt)p;y`E0hD;l<5W#kL8B0`{p6m_Y9q;J>4V-<0HTPhG7AkAW(806s={`ulXtuTI! zrqsA?TDP(>;A533IsL*}c+M@0C+AqwS3qL(2D_cf*k=mZtY zzhv9nJdoMcC7fN?kGZuifj6X5DXRo-9#wYWH))k7XqgS-{AehSoDCZP_j*2`4;|UG z0^9xe=>KIBC@Y>>zMY@tIYl`>I2=cA0)@D>*;>E9xooPjlV0p{S=9=*Cq;R!cL;P+ zT2^*wm5Foy<5PuV&T6Ft2e33IHdZXUiTW|UU=PpOonp? zFN7i2$G(;hLr82tcoy`K(Lc^CkucSUJ1`R#&Ck}x3$Cjrsm+P$#&DAkul^o80q?-v$>9da4oeS;fDI(fV*MF%)bT-JwOV4dyQa}b z64l>9#Xc)x?%NXr)hI~}ncf@>?6AFdDWqbAv)u2|wrI8*E>Wz_P>KP`4C;<_mPgFo zh6Jr5xCMo#&!uJ#AF>yTHElJ_6{Aa4r#~B0Ntn>6@((EWtfMV^IspXI@y9cAxm<0K ziC8pXiA&>^EZ`tX1U{*J8%#&Xw-!>kG4bTHUVj#2UjPmO06m@{ zNkXB@AgBr{fFOw5)amtlp|o%o1P!U0_)26OkN_aIvszyll= z>Vo6XFiNb-PnacW9-+YspOoXV&o5&h35BJlrJzIbXwg_1eZZ!;2PwLL^ug|MAVH6u zA>&hqKRS!*oshA~blqQFd2%&+c_qw4|HUagga25^i zZ?rFZxF1Ibr*OzZ**CcR;Nt^WzV@%+fm;6S3_NhjflCft68fU}f22e3rTB`i7tslt TU&41-q{IeG7mOexa4dwE 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 aC^{dB=(+vS8Hd5=>FXG1r|md){{H|2cv7YS literal 0 HcmV?d00001 diff --git a/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _size.snap.png b/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- _size.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..104cc896a6928b17441c35753c8117ee854c3547 GIT binary patch literal 4493 zcmeHLjZ>5N9e)Bv9Rtzc6sjp1t~X~!0g-`G2z2PBP7$pHgz-{DUTiUxpdjzL?GA3^ z2KK0;L`Zs^P@tG;uqg(J9cQD)5Gb>`7$LM0fvjLY&buFXJiq7p zy?x%kKls~`!z_2#Ev^JXxF2|T-+Kf>nI(VLtwE3CTixFYVq?sKeecAaqZq$B%Bfv@ zYt5)cVBeif^?Y5}c7#304GuV%>YwDKxU}T=>DJ2!W7zB7@u{AAf5EIZ+?B8zy!SZM zY35K>oGPW;CMa%CCwRSdBBFQ`A?$G_29jNfERhq@8S>h~ww_{(-%wCGReosblfLiH zTT2>6y^C~%!N3R$bDz)qM!3DoAQX?yhCdYX6ee7 zPJ4%*J8xHE)24+NPpGGZ`Gm3awOX)xQQ=vXsSE zqQkxKe3MqIrLM2E#aH(E@Rh%1^#!~((dyKh4>(f20;|)miA3hiq?DA*`ewJj^J1}> z2xIf+pX+3TCO)6vUAh!Zdp0aB=<4daH@LiHabUl-!Urobie7xbKUr4R0EvWi^YUs9 zDsX%=A>FHjD0Qdwt|PyB#F3CgIT8i8>%ocZcY*QX?&?DON-2lK35+^c?dRv`pfvck zg%gR1iDOe!zL3U~-5FGQVoHj^@*qR}d2IWYh6b03oOLt%->C5MpfMjv3#Ks`&;&&> zsOvAQ3=U}=_a*f=s@Mq)H(;LZP6>`-UssuBwd3N+IeG)BEL68S_?D8@jU-Ni1NDDcmulBO`D77mrBvFpwW1`BK5B0Fr;#YJ*Vn#B#U<8B&*%r zu0!nfRj~v1$0H*dV$I3=W{CJC$XQulYHcIJ+$jlLC_o z_wWwA3qee(MZ2ogNPrazgO6alk^t3W5f&yVebPoRk7es$JdwwD#4-{@Y8;$W)JnYFp`OH6fpTck z?C`_X>8}gk?%gnxjlh|b1pF3hf9-fDSTqZts>NEih>f3dS61qYk z$dV5GMR;ryUXV(qFFU~xrO3-fDO-Hn5?Z<#q-qTN<&1jKY7m&=bjUUOY8y8Q7w{NEueMWR#X>1&yK!@Nyq*J}QYCq4L9`Sp#HB_weMaYUZ zV`fpu~5T2gWTjDOoOAnaEPF3eZvKpE90SXf>rHiUZu@ zeK(U_yuHf9yiwa-G)K3$#)*>kMy;f^EipNH&BRrw&LF;$YhPI=Q?mQqi*1;^{M+w7 zx@$J5#F}jGnX_jvXtFm8>!36^_2ENy8$CzYt3-~$A+;ViHQ6SGzibSF0J{_}%%oPN zt{YHo5Z*+Nwzs!`uAaos$VC?y_kdP3_659Z%BAM*rgDJ|WP9)F&YorI7Lv~$KsRFx(`G4NHyWApU+u1z3 z_fLvj9O7WBQ%Np-jFOdCP*AsACO~UKw4&A4)?N_^GK2Xp3xRHwUN49eH3pKEWy*A9 zqsmD`dsX<>DSS6q5k2mXIs}W6#bUL)P7%XKtdp^g9fERb4GbxjQTfs&GFIDM2ZjJx zE>)Z?0w{rQk+6(7p~F;64nxf&U6u`c%9as>>X__l) zST3WHOn-wiiLGLiCRU9}P&7Mn6yZYhRa*Kc`9VL@J1B}wUIdfeqzuumDsY(NDXhWk ze5rC!uTO8I(+;xr$TAi{i=e^GIHPWQl?&zD75&H_evsyrzx z3Gh!!`SRJr(a~m64D01Uyu0NUWHOL(djmn{9**jp@#L}HEM=sEvvzIKKw|aX?R^(g< z4-HLKRaHc33@;x6;s{^T`OJ$5fec6CzH?$D$;CGg9!Sf!$BDq@+%xt_Zz;d+KKgmd z^oWB1$ug}|4WhnOdHQ2=Q|6oND?`gyLdnZPTwEM{O=kY-)nL2YW);7Cs~dAq6fpur2ovKu9VuQGJqy0v;GEX1O?RfrS)(2lWDoEcl>JCQWN2D6}E zGxmgqDRD7-k4-7s;?x=97U|6_xirkFGv@P8)st5VTs>?bLoS%(xUbVJc{zaL&=4>9 zj;s>vEAji!8+W&(BH_K~{=n(;AJ`pd!tl%eoqO-O-}%1p z+)1Knmtc{>#|AhYZjsQ1=Z3@KN6;U6K8(~q=}N-kOp1j(uKP*6riv@iToC!)^U;ZE zRr1x<=k5h5Zd8(`!3Xt(efMk_2gA9y?nqPYy#|>N?r&n4C3DLMNz(R%W)BG4l3oY7 zn{2;2Juvg{f_I^|A^t8djQ*G`{qvgo@lfSf1xt6ZD$GHq7qrc zz+m2^fB;q3@SBcJZ{ECN(?6nrv_Ky3chGcxV`C$G%a#Ds`K*`~pRr;#gqM9%T3QOP zr&Ft+S3VCpsOl>22wGN~_BgO6^bXH0*j(}K!o|dafnyhs_IybfcwRBS@;IsC@b$eR zH@mdy{pp(UdjDd-42z(kp#NyXog|arHSpYA%@y8l+R^>Kz7A@KUUsNhTotK&N!e$+ zl)gDypK9rv_2bjyC#S~OPfTUC7Wsz3d$!!=m1SDX6N#$-;f0M2!wq9&j$P5iiw1NV zloFq!v3G635&FST6RJ-!Vkgt4Bq@24#llrPoA2p#>je;0q?*oXc#(28-6?iDQy2NL z3C0tu@j@j_;eEHF!apnE$-sJb*5+Qd?)6iLMztDpzjDQfrBk>B29&m~*}0^bJ@le( ziSxOlit!{dJ^f;0M^HkZ^J1ZoMnBuqj&(NM1a;)s2#v=h>-@s%;7^>DjZd(37qS-^9|Tx&-#Uc_YsSY%ksLE@a;= zE8FHqF=upV&x~b{X@XXk-=^ZH#10? zsq~%E`I`T7ezcmhC1l;sCD}hoRDwrEwf2UPy`=HM0{z2aNp-MfcsXlosIxqxTA~Wb zus|7n*PotS^F>u(-%5pKYO$~|^ZW0`H#>sH+;6q55(ESUxV-u_t>ve07EsvFf=Z*U z+cf8L`$7}*RzRrj(uF{~42umH7BSi|p1@bS0E42xDOW&0aNxiiwF9HxNxlET0rAMs zP3A0J8dT)Y{O`MPGdAi7d+Ua2=g0eXzkYps zcsMNHkMpSC4?N<~Y(~#Rx+#vBNx&>9pO_AmwLQO`rQ5*FS02r{4f@Hjklz;{F7dwZ zUHD+f(qxhVxF3=AG^i9X1#5WuGQK0IwzoE=ZU;-Zj+tLFB~b%Z!%hxzbC3*BY&sRe zRGmPH7<%zHKnZkT+@*~G6M*-pdu2$^Uuj085cQnYnc3OH4>xxG2+9|Mx`S0y=MpH4 zP&QrvwwCc!JBpdbqjfvMV#01h(D*=6-Hz$K>2;ukeMPPG12E2}r?zYdwt#uPjPO_b z41@5e_ahGgFe9?=+`YTi%`P!796Ydj-5MxSmecb?W3R3hnbxKq%>XxZd1ao~(x}m_ z5u$UEkN7)H_p{I@WSx|dZ zP$>ud^Nr8g$Yka5IKw_?#KIRTZQAjp_lrRs#%|3&80AXD-^$oF+ zPM?DALmfi@QuY(7PxKS2KIJ@xWM6P6Yhv?`=6h^;w85}b*v-ARx68|UkBWSm`DcrZ z9ppgp?4QER`hI@>+EBO|tTh6NE&$579x3Yxy@~X>4ML&P_J**GfARA}ZO1pjlf5A- zF<64eDRM-X3(os8;^m=P500f!pn{nKebmo2q-I@y6f#!EQhp~W?9}lFwb9_FM*tc zf`g%-T)40tx}@F_jLf@m@9Og|uf9SWyt5yC4Qn^G9UY&5Vsj1-rlOgBsM3%L4No#8>RIUlyo2L!*{q(vou6F|;p`}B? z0aMJ#er(g6oYb$GGrC({S_D;A035xiM+z;GfnbV+&JF7FD}FjSt~&-MQ{=093Gc=9 zv=&!pej%8}g^j`BcwkNyV=tFOt7Zg(U^S&(Lxaz^0jIZ2>&+*oRtTqna~aruL=Hi| zu~X~Q>lii;5z~{7U=z6@bqH2O3Rxvz$HY8zQiJhiZH~I1J@B*`15@qb<>iGniN>JP zLs);SJ7XDb>l>pp?qx%lDeL%17{gLLyQ5V0{R}BKyf{?1WA*CQ?7K=O-;DtphV%h7 z@W`Up=;N@dm<~wpX#N&!c;!)}zxMZM$U;zWgt`gQ;NJwHbFI&rS2Fy4qIf+RqFe4<5N~7>39%na^yW0p)~5QgI5;!|g^OrZt_PL+J|0iglC;L}7vaNe;wZsD7H2Js z>rr+qrQ{ql=?`S-4`u`_@*5J(2<=dAQtoBM-OVF;DrJRfR8T6Um6>UJ}aOd(V zH)&tkX(P)ikdc$nim;ZISsa0xa}shxYhejNJW*tX^5+mCt5G;R9GPi_oju1a$6z*o zQaIh;ylFZx4w>89Gr2$#=;o;-^`LXR3cYjzWyK&v=v=vF>e$;J|8CdCnMAHJk0_ub ztoTMEBPz{^nn|>T?Tp}w&WBC$G%ny$wVM|L(EtbJT_r^09sn|$TP4Ji@H8X99ZjSX z-Qj?Ih@Km-62dc{#Kj>%&{P2z4ns3~KMsRD$B8A60DfgGh{0n z*+ACKl15QQMz9^)RAf}Odp28GZ)SCl8Pm#)8OKCKup&!yWjS$Bkl&6I2nI|k0ex

FZ#5A^qCu3kF)!mpY^2l@-yKy*pJp6-aF0c^F zO++CAK9^%m6x9gPIyLT91!ItCIi_>}&#$b{kkvjv@@m zmkB`0%hrU;*7AbXycBD=8tb+!@Qsc5BYk+Yr1=Z_kml$Ea^Q+Mhz?NmU+ELFm}3ls z)J)(YK!jD;5@;wwiprd06{e@((nm?&#mq57DuBYX6T3k-GSJO!lR0Ye(P|j;Kr@!q z_GByqi*QgK;uk5^@;W$UsJxLv$vvl!xL$ z!%$Kb4782CF>`_}hfCcabkQ2unZ}<2BUdjQ!^Mtnr0C03+($)~;Mf1rj()f*{7+sL ze*bHM-Cy4)J_P;YSCtPq1%80w0|fAk(g(x%0Kxwq3p!^O^xN*yjW^R?z_0i?A%7R| J+SY^8{{mDQ^b!C7 literal 0 HcmV?d00001 diff --git a/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- simple.snap.png b/cypress/snapshots/web/components/Slider/Slider.component-test.tsx/plasma-web Slider -- simple.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..5a2dd31dc86045a65a30bad4627bdc02f458db99 GIT binary patch literal 6166 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 literal 0 HcmV?d00001 diff --git a/packages/plasma-b2c/api/plasma-b2c.api.md b/packages/plasma-b2c/api/plasma-b2c.api.md index 7a8837d0af..76cd0b5701 100644 --- a/packages/plasma-b2c/api/plasma-b2c.api.md +++ b/packages/plasma-b2c/api/plasma-b2c.api.md @@ -93,6 +93,7 @@ import { defaultValidate } from '@salutejs/plasma-hope'; import { DisabledProps } from '@salutejs/plasma-core'; import { DividerProps } from '@salutejs/plasma-new-hope/styled-components'; import { dividerTokens } from '@salutejs/plasma-new-hope/styled-components'; +import { DoubleSliderProps } from '@salutejs/plasma-new-hope/styled-components'; import { DrawerContentProps } from '@salutejs/plasma-new-hope/styled-components'; import { DrawerFooterProps } from '@salutejs/plasma-new-hope/styled-components'; import { DrawerHeaderProps } from '@salutejs/plasma-new-hope/styled-components'; @@ -200,10 +201,11 @@ import { setRef } from '@salutejs/plasma-core'; import { shadows } from '@salutejs/plasma-core'; import { ShiftProps } from '@salutejs/plasma-core'; import { ShowToastArgs } from '@salutejs/plasma-new-hope/styled-components'; +import { SingleSliderProps } from '@salutejs/plasma-new-hope/styled-components'; import { SkeletonGradientProps } from '@salutejs/plasma-core'; import { SkeletonGradientProps as SkeletonGradientProps_2 } from '@salutejs/plasma-new-hope/styled-components'; import { SkeletonSizeProps } from '@salutejs/plasma-new-hope/types/components/Skeleton/Skeleton.types'; -import { SliderProps } from '@salutejs/plasma-core'; +import { SliderProps } from '@salutejs/plasma-new-hope/styled-components'; import { SmartPaginationDots } from '@salutejs/plasma-hope'; import { SmartPaginationDotsProps } from '@salutejs/plasma-hope'; import { SnapAlign } from '@salutejs/plasma-core'; @@ -773,11 +775,19 @@ l: string; view: { default: string; }; +<<<<<<< HEAD }> & ((Omit, "type" | "target" | "onChange" | "size" | "value" | "checked" | "maxLength" | "minLength"> & CustomComboboxProps & { valueType?: "single" | undefined; value?: ComboboxPrimitiveValue | undefined; onChangeValue?: ((value?: ComboboxPrimitiveValue | undefined) => void) | undefined; } & RefAttributes) | (Omit, "type" | "target" | "onChange" | "size" | "value" | "checked" | "maxLength" | "minLength"> & CustomComboboxProps & { +======= +}> & ((Omit, "onChange" | "type" | "target" | "size" | "value" | "checked" | "minLength" | "maxLength"> & CustomComboboxProps & { +valueType?: "single" | undefined; +value?: ComboboxPrimitiveValue | undefined; +onChangeValue?: ((value?: ComboboxPrimitiveValue | undefined) => void) | undefined; +} & RefAttributes) | (Omit, "onChange" | "type" | "target" | "size" | "value" | "checked" | "minLength" | "maxLength"> & CustomComboboxProps & { +>>>>>>> a61c59f64 (Update package-lock.json files) valueType: "multiple"; value?: ComboboxPrimitiveValue[] | undefined; onChangeValue?: ((value?: ComboboxPrimitiveValue[] | undefined) => void) | undefined; @@ -1162,7 +1172,7 @@ true: string; // @public const Image_2: FunctionComponent & ImgHTMLAttributes & { -base?: "div" | "img" | undefined; +base?: "img" | "div" | undefined; ratio?: "16 / 9" | "1 / 1" | "1/1" | "3 / 4" | "3/4" | "4 / 3" | "4/3" | "9 / 16" | "9/16" | "16/9" | "1 / 2" | "1/2" | "2 / 1" | "2/1" | undefined; customRatio?: string | undefined; } & RefAttributes>; @@ -1595,8 +1605,22 @@ export { ShowToastArgs } export { SkeletonGradientProps } -// @public (undocumented) -export const Slider: (props: SliderProps) => JSX.Element; +// @public +export const Slider: FunctionComponent & ((SingleSliderProps & RefAttributes) | (DoubleSliderProps & RefAttributes))>; export { SliderProps } diff --git a/packages/plasma-b2c/src/components/Slider/Slider.component-test.tsx b/packages/plasma-b2c/src/components/Slider/Slider.component-test.tsx index 4c9a39bbd8..1f6917482a 120000 --- a/packages/plasma-b2c/src/components/Slider/Slider.component-test.tsx +++ b/packages/plasma-b2c/src/components/Slider/Slider.component-test.tsx @@ -1 +1 @@ -../../../../plasma-core/src/components/Slider/Slider.component-test.tsx \ No newline at end of file +../../../../plasma-web/src/components/Slider/Slider.component-test.tsx \ No newline at end of file diff --git a/packages/plasma-b2c/src/components/Slider/Slider.config.ts b/packages/plasma-b2c/src/components/Slider/Slider.config.ts new file mode 100644 index 0000000000..065c9212f8 --- /dev/null +++ b/packages/plasma-b2c/src/components/Slider/Slider.config.ts @@ -0,0 +1,241 @@ +import { css, sliderTokens } from '@salutejs/plasma-new-hope/styled-components'; + +export const config = { + defaults: { + view: 'default', + size: 'm', + }, + variations: { + view: { + default: css` + ${sliderTokens.labelColor}: var(--text-primary); + + ${sliderTokens.rangeValueColor}: var(--text-secondary); + + ${sliderTokens.thumbBorderColor}: var(--surface-solid-tertiary); + ${sliderTokens.thumbBackgroundColor}: var(--on-light-surface-solid-card); + ${sliderTokens.thumbFocusBorderColor}: var(--surface-solid-default); + + ${sliderTokens.railBackgroundColor}: var(--surface-solid-tertiary); + + ${sliderTokens.fillColor}: var(--surface-solid-default); + + ${sliderTokens.textFieldColor}: var(--text-secondary); + ${sliderTokens.textFieldBackgroundColor}: var(--surface-transparent-primary); + ${sliderTokens.textFieldCaretColor}: var(--text-primary); + ${sliderTokens.textFieldPlaceholderColor}: var(--text-secondary); + ${sliderTokens.textFiledFocusColor}: var(--text-primary); + ${sliderTokens.textFieldActiveColor}: var(--text-primary); + `, + accent: css` + ${sliderTokens.labelColor}: var(--text-primary); + + ${sliderTokens.rangeValueColor}: var(--text-secondary); + + ${sliderTokens.thumbBorderColor}: var(--surface-solid-tertiary); + ${sliderTokens.thumbBackgroundColor}: var(--on-light-surface-solid-card); + ${sliderTokens.thumbFocusBorderColor}: var(--surface-accent); + + ${sliderTokens.railBackgroundColor}: var(--surface-solid-tertiary); + + ${sliderTokens.fillColor}: var(--surface-accent); + + ${sliderTokens.textFieldColor}: var(--text-secondary); + ${sliderTokens.textFieldBackgroundColor}: var(--surface-transparent-primary); + ${sliderTokens.textFieldCaretColor}: var(--text-primary); + ${sliderTokens.textFieldPlaceholderColor}: var(--text-secondary); + ${sliderTokens.textFiledFocusColor}: var(--text-primary); + ${sliderTokens.textFieldActiveColor}: var(--text-primary); + `, + gradient: css` + ${sliderTokens.labelColor}: var(--text-primary); + + ${sliderTokens.rangeValueColor}: var(--text-secondary); + + ${sliderTokens.thumbBorderColor}: var(--surface-solid-tertiary); + ${sliderTokens.thumbBackgroundColor}: var(--on-light-surface-solid-card); + ${sliderTokens.thumbFocusBorderColor}: var(--surface-accent-gradient); + + ${sliderTokens.railBackgroundColor}: var(--surface-solid-tertiary); + + ${sliderTokens.fillColor}: var(--surface-accent-gradient); + + ${sliderTokens.textFieldColor}: var(--text-secondary); + ${sliderTokens.textFieldBackgroundColor}: var(--surface-transparent-primary); + ${sliderTokens.textFieldCaretColor}: var(--text-primary); + ${sliderTokens.textFieldPlaceholderColor}: var(--text-secondary); + ${sliderTokens.textFiledFocusColor}: var(--text-primary); + ${sliderTokens.textFieldActiveColor}: var(--text-primary); + `, + }, + size: { + l: css` + ${sliderTokens.height}: 1.5rem; + ${sliderTokens.doubleWrapperGap}: 0.375rem; + + ${sliderTokens.labelWrapperGap}: 0.25rem; + ${sliderTokens.labelWrapperMarginBottom}: 0.25rem; + ${sliderTokens.labelWrapperMarginRight}: 0.875rem; + + ${sliderTokens.labelFontFamily}: var(--plasma-typo-body-l-font-family); + ${sliderTokens.labelFontSize}: var(--plasma-typo-body-l-font-size); + ${sliderTokens.labelFontStyle}: var(--plasma-typo-body-l-font-style); + ${sliderTokens.labelFontWeight}: var(--plasma-typo-body-l-font-weight); + ${sliderTokens.labelLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${sliderTokens.labelLineHeight}: var(--plasma-typo-body-l-line-height); + + ${sliderTokens.rangeMinValueMargin}: 0.75rem; + ${sliderTokens.rangeMaxValueMargin}: 0.75rem; + ${sliderTokens.rangeValueBottomOffset}: -1.25rem; + + ${sliderTokens.rangeValueFontFamily}: var(--plasma-typo-body-s-font-family); + ${sliderTokens.rangeValueFontSize}: var(--plasma-typo-body-s-font-size); + ${sliderTokens.rangeValueFontStyle}: var(--plasma-typo-body-s-font-style); + ${sliderTokens.rangeValueFontWeight}: var(--plasma-typo-body-s-font-weight); + ${sliderTokens.rangeValueLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${sliderTokens.rangeValueLineHeight}: var(--plasma-typo-body-s-line-height); + + ${sliderTokens.thumbSize}: 1.5rem; + ${sliderTokens.thumbBorder}: 0.125rem solid; + + ${sliderTokens.currentValueTopOffset}: 1.625rem; + + ${sliderTokens.currentValueFontFamily}: var(--plasma-typo-text-s-font-family); + ${sliderTokens.currentValueFontSize}: var(--plasma-typo-text-s-font-size); + ${sliderTokens.currentValueFontStyle}: var(--plasma-typo-text-s-font-style); + ${sliderTokens.currentValueFontWeight}: var(--plasma-typo-text-s-font-weight); + ${sliderTokens.currentValueLetterSpacing}: var(--plasma-typo-text-s-letter-spacing); + ${sliderTokens.currentValueLineHeight}: var(--plasma-typo-text-s-line-height); + + ${sliderTokens.railHeight}: 0.25rem; + ${sliderTokens.railBorderRadius}: 0.125rem; + ${sliderTokens.railIndent}: 0.75rem; + + ${sliderTokens.textFieldWrapperGap}: 0.125rem; + + ${sliderTokens.textFieldHeight}: 3.5rem; + ${sliderTokens.textFieldPadding}: 1.25rem 1rem 1.25rem 1rem; + ${sliderTokens.textFieldBorderRadius}: 0.75rem; + ${sliderTokens.textFieldFontFamily}: var(--plasma-typo-body-l-font-family); + ${sliderTokens.textFieldFontSize}: var(--plasma-typo-body-l-font-size); + ${sliderTokens.textFieldFontStyle}: var(--plasma-typo-body-l-font-style); + ${sliderTokens.textFieldFontWeight}: var(--plasma-typo-body-l-font-weight); + ${sliderTokens.textFieldLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${sliderTokens.textFieldLineHeight}: var(--plasma-typo-body-l-line-height); + `, + m: css` + ${sliderTokens.height}: 1.5rem; + ${sliderTokens.doubleWrapperGap}: 0.375rem; + + ${sliderTokens.labelWrapperGap}: 0.25rem; + ${sliderTokens.labelWrapperMarginBottom}: 0.25rem; + ${sliderTokens.labelWrapperMarginRight}: 0.875rem; + + ${sliderTokens.labelFontFamily}: var(--plasma-typo-body-m-font-family); + ${sliderTokens.labelFontSize}: var(--plasma-typo-body-m-font-size); + ${sliderTokens.labelFontStyle}: var(--plasma-typo-body-m-font-style); + ${sliderTokens.labelFontWeight}: var(--plasma-typo-body-m-font-weight); + ${sliderTokens.labelLetterSpacing}: var(--plasma-typo-body-m-letter-spacing); + ${sliderTokens.labelLineHeight}: var(--plasma-typo-body-m-line-height); + + ${sliderTokens.rangeMinValueMargin}: 0.75rem; + ${sliderTokens.rangeMaxValueMargin}: 0.75rem; + ${sliderTokens.rangeValueBottomOffset}: -1.25rem; + + ${sliderTokens.rangeValueFontFamily}: var(--plasma-typo-body-s-font-family); + ${sliderTokens.rangeValueFontSize}: var(--plasma-typo-body-s-font-size); + ${sliderTokens.rangeValueFontStyle}: var(--plasma-typo-body-s-font-style); + ${sliderTokens.rangeValueFontWeight}: var(--plasma-typo-body-s-font-weight); + ${sliderTokens.rangeValueLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${sliderTokens.rangeValueLineHeight}: var(--plasma-typo-body-s-line-height); + + ${sliderTokens.thumbSize}: 1.5rem; + ${sliderTokens.thumbBorder}: 0.125rem solid; + + ${sliderTokens.currentValueTopOffset}: 1.75rem; + + ${sliderTokens.currentValueFontFamily}: var(--plasma-typo-text-xs-font-family); + ${sliderTokens.currentValueFontSize}: var(--plasma-typo-text-xs-font-size); + ${sliderTokens.currentValueFontStyle}: var(--plasma-typo-text-xs-font-style); + ${sliderTokens.currentValueFontWeight}: var(--plasma-typo-text-xs-font-weight); + ${sliderTokens.currentValueLetterSpacing}: var(--plasma-typo-text-xs-letter-spacing); + ${sliderTokens.currentValueLineHeight}: var(--plasma-typo-text-xs-line-height); + + ${sliderTokens.railHeight}: 0.25rem; + ${sliderTokens.railBorderRadius}: 0.125rem; + ${sliderTokens.railIndent}: 0.75rem; + + ${sliderTokens.textFieldWrapperGap}: 0.125rem; + + ${sliderTokens.textFieldHeight}: 3rem; + ${sliderTokens.textFieldPadding}: 0.875rem 1rem 0.875rem 1rem; + ${sliderTokens.textFieldBorderRadius}: 0.75rem; + ${sliderTokens.textFieldFontFamily}: var(--plasma-typo-body-m-font-family); + ${sliderTokens.textFieldFontSize}: var(--plasma-typo-body-m-font-size); + ${sliderTokens.textFieldFontStyle}: var(--plasma-typo-body-m-font-style); + ${sliderTokens.textFieldFontWeight}: var(--plasma-typo-body-m-font-weight); + ${sliderTokens.textFieldLetterSpacing}: var(--plasma-typo-body-m-letter-spacing); + ${sliderTokens.textFieldLineHeight}: var(--plasma-typo-body-m-line-height); + `, + s: css` + ${sliderTokens.height}: 1rem; + ${sliderTokens.doubleWrapperGap}: 0.375rem; + + ${sliderTokens.labelWrapperGap}: 0.25rem; + ${sliderTokens.labelWrapperMarginBottom}: 0.25rem; + ${sliderTokens.labelWrapperMarginRight}: 0.875rem; + + ${sliderTokens.labelFontFamily}: var(--plasma-typo-body-s-font-family); + ${sliderTokens.labelFontSize}: var(--plasma-typo-body-s-font-size); + ${sliderTokens.labelFontStyle}: var(--plasma-typo-body-s-font-style); + ${sliderTokens.labelFontWeight}: var(--plasma-typo-body-s-font-weight); + ${sliderTokens.labelLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${sliderTokens.labelLineHeight}: var(--plasma-typo-body-s-line-height); + + ${sliderTokens.rangeMinValueMargin}: 0.5rem; + ${sliderTokens.rangeMaxValueMargin}: 0.5rem; + ${sliderTokens.rangeValueBottomOffset}: -1.25rem; + + ${sliderTokens.rangeValueFontFamily}: var(--plasma-typo-body-xs-font-family); + ${sliderTokens.rangeValueFontSize}: var(--plasma-typo-body-xs-font-size); + ${sliderTokens.rangeValueFontStyle}: var(--plasma-typo-body-xs-font-style); + ${sliderTokens.rangeValueFontWeight}: var(--plasma-typo-body-xs-font-weight); + ${sliderTokens.rangeValueLetterSpacing}: var(--plasma-typo-body-xs-letter-spacing); + ${sliderTokens.rangeValueLineHeight}: var(--plasma-typo-body-xs-line-height); + + ${sliderTokens.thumbSize}: 1rem; + ${sliderTokens.thumbBorder}: 0.125rem solid; + + ${sliderTokens.currentValueTopOffset}: 1.25rem; + + ${sliderTokens.currentValueFontFamily}: var(--plasma-typo-text-xs-font-family); + ${sliderTokens.currentValueFontSize}: var(--plasma-typo-text-xs-font-size); + ${sliderTokens.currentValueFontStyle}: var(--plasma-typo-text-xs-font-style); + ${sliderTokens.currentValueFontWeight}: var(--plasma-typo-text-xs-font-weight); + ${sliderTokens.currentValueLetterSpacing}: var(--plasma-typo-text-xs-letter-spacing); + ${sliderTokens.currentValueLineHeight}: var(--plasma-typo-text-xs-line-height); + + ${sliderTokens.railHeight}: 0.25rem; + ${sliderTokens.railBorderRadius}: 0.125rem; + ${sliderTokens.railIndent}: 0.75rem; + + ${sliderTokens.textFieldWrapperGap}: 0.125rem; + + ${sliderTokens.textFieldHeight}: 2.5rem; + ${sliderTokens.textFieldPadding}: 0.5rem 1rem 0.5rem 1rem; + ${sliderTokens.textFieldBorderRadius}: 0.625rem; + ${sliderTokens.textFieldFontFamily}: var(--plasma-typo-body-s-font-family); + ${sliderTokens.textFieldFontSize}: var(--plasma-typo-body-s-font-size); + ${sliderTokens.textFieldFontStyle}: var(--plasma-typo-body-s-font-style); + ${sliderTokens.textFieldFontWeight}: var(--plasma-typo-body-s-font-weight); + ${sliderTokens.textFieldLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${sliderTokens.textFieldLineHeight}: var(--plasma-typo-body-s-line-height); + `, + }, + disabled: { + true: css` + ${sliderTokens.disabledOpacity}: 0.4; + `, + }, + }, +}; diff --git a/packages/plasma-b2c/src/components/Slider/Slider.stories.tsx b/packages/plasma-b2c/src/components/Slider/Slider.stories.tsx index 111a1f9824..276bdd7eea 100644 --- a/packages/plasma-b2c/src/components/Slider/Slider.stories.tsx +++ b/packages/plasma-b2c/src/components/Slider/Slider.stories.tsx @@ -1,22 +1,38 @@ import React, { useState } from 'react'; +import type { ComponentProps } from 'react'; import styled from 'styled-components'; import { InSpacingDecorator, disableProps } from '@salutejs/plasma-sb-utils'; -import type { Meta, StoryObj } from '@storybook/react'; +import type { StoryObj, Meta } from '@storybook/react'; import { action } from '@storybook/addon-actions'; -import { Slider, SliderProps, SliderProps as DoubleSliderProps } from '.'; +import { Slider } from './Slider'; -const meta: Meta = { +const sizes = ['l', 'm', 's']; +const views = ['default', 'accent', 'gradient']; +const labelPlacements = ['outer', 'inner']; +const rangeValuesPlacement = ['outer', 'inner']; + +const meta: Meta = { title: 'Controls/Slider', component: Slider, decorators: [InSpacingDecorator], argTypes: { + view: { + options: views, + control: { + type: 'select', + }, + }, + size: { + options: sizes, + control: { + type: 'inline-radio', + }, + }, ...disableProps([ 'value', 'onChangeCommitted', - 'theme', - 'as', - 'forwardedAs', + 'ariaLabel', 'onChange', 'fontSizeMultiplier', 'gap', @@ -24,22 +40,21 @@ const meta: Meta = { 'hasHoverAnimation', ]), }, - args: { - min: 0, - max: 100, - disabled: false, - ariaLabel: ['Минимальная цена товара', 'Максимальная цена товара'], - multipleStepSize: 10, - }, }; export default meta; +type StoryProps = Omit, 'value' | 'onChangeCommitted'>; +type StorySingleProps = StoryProps; + +type StorySingle = StoryObj; +type StoryDouble = StoryObj; + const SliderWrapper = styled.div` width: 25rem; `; -const StoryDefault = (args: SliderProps) => { +const StoryDefault = (args: StorySingleProps) => { const [value, setValue] = useState(30); const onChangeCommittedHandle = (values) => { @@ -48,29 +63,86 @@ const StoryDefault = (args: SliderProps) => { return ( - + ); }; -export const Default: StoryObj = { +export const Default: StorySingle = { + argTypes: { + labelPlacement: { + options: labelPlacements, + control: { + type: 'inline-radio', + }, + }, + rangeValuesPlacement: { + options: rangeValuesPlacement, + control: { + type: 'inline-radio', + }, + }, + }, + args: { + view: 'default', + size: 'm', + min: 0, + max: 100, + disabled: false, + ariaLabel: 'Цена товара', + multipleStepSize: 10, + label: 'Цена товара', + labelPlacement: 'outer', + rangeValuesPlacement: 'outer', + showRangeValues: true, + showCurrentValue: false, + }, render: (args) => , }; -const StoryMultipleValues = (args: DoubleSliderProps) => { +const StoryMultipleValues = (args: StoryProps) => { const [value, setValue] = useState([10, 80]); + const sortValues = (values) => { + return values.sort((a, b) => a - b); + }; - const onChangeCommittedHandle = (values) => { - setValue(values); + const onChangeHandle = (values) => { + setValue(sortValues(values)); + }; + + const onBlurTextField = (values) => { + setValue(sortValues(values)); + }; + + const onKeyDownTextField = (values, event) => { + if (event.key === 'Enter') { + setValue(sortValues(values)); + } }; return ( - + ); }; -export const MultipleValues: StoryObj = { +export const MultipleValues: StoryDouble = { + args: { + view: 'default', + size: 'm', + min: 0, + max: 100, + disabled: false, + label: 'Цена товара', + ariaLabel: ['Минимальная цена товара', 'Максимальная цена товара'], + multipleStepSize: 10, + }, render: (args) => , }; diff --git a/packages/plasma-b2c/src/components/Slider/Slider.tsx b/packages/plasma-b2c/src/components/Slider/Slider.tsx index 1507788c15..9fbafc706c 100644 --- a/packages/plasma-b2c/src/components/Slider/Slider.tsx +++ b/packages/plasma-b2c/src/components/Slider/Slider.tsx @@ -1,22 +1,12 @@ -import React from 'react'; -import styled from 'styled-components'; -import { SliderCore, SliderProps, SliderSettings } from '@salutejs/plasma-core'; -import { SliderThumb } from '@salutejs/plasma-hope'; -import { accent, white, surfaceLiquid03, buttonAccent as fillColor } from '@salutejs/plasma-tokens-b2c'; +import { sliderConfig, component, mergeConfig } from '@salutejs/plasma-new-hope/styled-components'; -const sliderSettings: SliderSettings = { - backgroundColor: surfaceLiquid03, - fillColor, -}; +import { config } from './Slider.config'; -const StyledThumb = styled(SliderThumb)` - border-color: ${surfaceLiquid03}; +const mergedConfig = mergeConfig(sliderConfig, config); +const SliderComponent = component(mergedConfig); - background-color: ${white}; - - color: ${accent}; -`; - -export const Slider = (props: SliderProps) => { - return ; -}; +/** + * Слайдер позволяет определить числовое значение в пределах указанного промежутка. + * Можно указать два значения. + */ +export const Slider = SliderComponent; diff --git a/packages/plasma-b2c/src/components/Slider/index.ts b/packages/plasma-b2c/src/components/Slider/index.ts index d287135b08..737e414a4b 100644 --- a/packages/plasma-b2c/src/components/Slider/index.ts +++ b/packages/plasma-b2c/src/components/Slider/index.ts @@ -1,2 +1,2 @@ export { Slider } from './Slider'; -export type { SliderProps } from '@salutejs/plasma-core'; +export type { SliderProps } from '@salutejs/plasma-new-hope/styled-components'; diff --git a/packages/plasma-new-hope/src/components/Slider/Slider.tokens.ts b/packages/plasma-new-hope/src/components/Slider/Slider.tokens.ts new file mode 100644 index 0000000000..53822c72e9 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/Slider.tokens.ts @@ -0,0 +1,88 @@ +export const classes = { + labelPlacementOuter: 'slider-label-placement-outer', + labelPlacementInner: 'slider-label-placement-inner', + rangeValuesPlacementOuter: 'slider-range-values-placement-outer', + rangeValuesPlacementInner: 'slider-range-values-placement-inner', + maxRangeValue: 'slider-max-range-value', + hideMinValue: 'slider-hide-min-value', + hideMaxValue: 'slider-hide-max-value', + textFieldActive: 'slider-text-field-active', + firstTextField: 'slider-first-text-field', + secondTextField: 'slider-second-text-field', + activeRangeValue: 'slider-active-range-value', +}; + +export const tokens = { + height: '--plasma-slider-height', + + labelWrapperGap: '--plasma-slider-label-wrapper-gap', + labelWrapperMarginBottom: '--plasma-slider-label-wrapper-margin-bottom', + labelWrapperMarginRight: '--plasma-slider-label-wrapper-margin-right', + + labelColor: '--plasma-slider-label-color', + labelFontFamily: '--plasma-slider-label-font-family', + labelFontSize: '--plasma-slider-label-font-size', + labelFontStyle: '--plasma-slider-label-font-style', + labelFontWeight: '--plasma-slider-label-font-weight', + labelLetterSpacing: '--plasma-slider-label-letter-spacing', + labelLineHeight: '--plasma-slider-label-line-height', + + rangeMinValueMargin: '--plasma-slider-range-min-value-margin', + rangeMaxValueMargin: '--plasma-slider-range-max-value-margin', + rangeValueBottomOffset: '--plasma-slider-range-value-bottom-offset', + + rangeValueColor: '--plasma-slider-range-value-color', + rangeValueFontFamily: '--plasma-slider-range-value-font-family', + rangeValueFontSize: '--plasma-slider-range-value-font-size', + rangeValueFontStyle: '--plasma-slider-range-value-font-style', + rangeValueFontWeight: '--plasma-slider-range-value-font-weight', + rangeValueLetterSpacing: '--plasma-slider-range-value-letter-spacing', + rangeValueLineHeight: '--plasma-slider-range-value-line-height', + + doubleWrapperGap: '--plasma-slider-double-wrapper-gap', + + thumbSize: '--plasma-slider-thumb-size', + thumbBorder: '--plasma-slider-thumb-border', + thumbBorderColor: '--plasma-slider-thumb-border-color', + thumbBackgroundColor: '--plasma-slider-thumb-background-color', + + thumbFocusBorderColor: '--plasma-slider-thumb-focus-border-color', + + currentValueTopOffset: '--plasma-slider-current-value-top-offset', + + currentValueFontFamily: '--plasma-slider-current-value-font-family', + currentValueFontSize: '--plasma-slider-current-value-font-size', + currentValueFontStyle: '--plasma-slider-current-value-font-style', + currentValueFontWeight: '--plasma-slider-current-value-font-weight', + currentValueLetterSpacing: '--plasma-slider-current-value-letter-spacing', + currentValueLineHeight: '--plasma-slider-current-value-line-height', + + railBackgroundColor: '--plasma-slider-rail-background-color', + railHeight: '--plasma-slider-rail-height', + railBorderRadius: '--plasma-slider-rail-border-radius', + railIndent: '--plasma-slider-rail-indent', + + fillColor: '--plasma-slider-fill-color', + + textFieldWrapperGap: '--plasma-slider-text-field-wrapper-gap', + + textFieldFontFamily: '--plasma-slider-text-field-font-family', + textFieldFontSize: '--plasma-slider-text-field-font-size', + textFieldFontStyle: '--plasma-slider-text-field-font-style', + textFieldFontWeight: '--plasma-slider-text-field-font-weight', + textFieldLetterSpacing: '--plasma-slider-text-field-letter-spacing', + textFieldLineHeight: '--plasma-slider-text-field-line-height', + + textFieldHeight: '--plasma-slider-text-field-height', + textFieldPadding: '--plasma-slider-text-field-padding', + textFieldBorderRadius: '--plasma-slider-text-field-border-radius', + + textFieldColor: '--plasma-slider-text-field-color', + textFieldActiveColor: '--plasma-slider-text-field-active-color', + textFieldBackgroundColor: '--plasma-slider-text-field-background-color', + textFieldCaretColor: '--plasma-slider-text-field-caret-color', + textFieldPlaceholderColor: '--plasma-slider-text-field-placeholder-color', + textFiledFocusColor: '--plasma-slider-text-field-focus-color', + + disabledOpacity: '--plasma-slider-disabled-opacity', +}; diff --git a/packages/plasma-new-hope/src/components/Slider/Slider.tsx b/packages/plasma-new-hope/src/components/Slider/Slider.tsx new file mode 100644 index 0000000000..2d71997db0 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/Slider.tsx @@ -0,0 +1,51 @@ +import React, { forwardRef } from 'react'; + +import type { RootPropsOmitOnChange } from '../../engines'; + +import { base as viewCSS } from './variations/_view/base'; +import { base as sizeCSS } from './variations/_size/base'; +import { base as disabledCSS } from './variations/_disabled/base'; +import { SingleSlider, DoubleSlider } from './components'; +import type { SingleSliderProps } from './components'; +import { SliderProps } from './Slider.types'; + +const isSingleValueProps = (props: SliderProps): props is SingleSliderProps => typeof props.value === 'number'; + +export const sliderRoot = (Root: RootPropsOmitOnChange) => + forwardRef((props, ref) => { + if (isSingleValueProps(props)) { + return ( + + + + ); + } + return ( + + + + ); + }); + +export const sliderConfig = { + name: 'Slider', + tag: 'div', + layout: sliderRoot, + base: '', + variations: { + view: { + css: viewCSS, + }, + size: { + css: sizeCSS, + }, + disabled: { + css: disabledCSS, + attrs: true, + }, + }, + defaults: { + view: 'default', + size: 'm', + }, +}; diff --git a/packages/plasma-new-hope/src/components/Slider/Slider.types.ts b/packages/plasma-new-hope/src/components/Slider/Slider.types.ts new file mode 100644 index 0000000000..46c8189664 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/Slider.types.ts @@ -0,0 +1,3 @@ +import type { DoubleSliderProps, SingleSliderProps } from './components'; + +export type SliderProps = SingleSliderProps | DoubleSliderProps; diff --git a/packages/plasma-new-hope/src/components/Slider/components/Double/Double.styles.ts b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.styles.ts new file mode 100644 index 0000000000..55dfcc280c --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.styles.ts @@ -0,0 +1,75 @@ +import { styled } from '@linaria/react'; + +import { classes, tokens } from '../../Slider.tokens'; +import { component, mergeConfig } from '../../../../engines'; +import { textFieldConfig, textFieldTokens } from '../../../TextField'; + +const mergedConfig = mergeConfig(textFieldConfig); +const TextField = component(mergedConfig); + +export const LabelWrapper = styled.div` + color: var(${tokens.labelColor}); + + display: flex; + gap: var(${tokens.labelWrapperGap}); + margin-bottom: var(${tokens.labelWrapperMarginBottom}); +`; + +export const LabelContentLeft = styled.div``; + +export const Label = styled.label` + font-family: var(${tokens.labelFontFamily}); + font-size: var(${tokens.labelFontSize}); + font-style: var(${tokens.labelFontStyle}); + font-weight: var(${tokens.labelFontWeight}); + letter-spacing: var(${tokens.labelLetterSpacing}); + line-height: var(${tokens.labelLineHeight}); +`; + +export const InputsWrapper = styled.div` + display: flex; + gap: var(${tokens.textFieldWrapperGap}); + margin-top: var(${tokens.doubleWrapperGap}); +`; + +// NOTE: переопределение токенов TextField +export const StyledInput = styled(TextField)` + flex: 1; + + ${textFieldTokens.color}: var(${tokens.textFieldColor}); + ${textFieldTokens.backgroundColor}: var(${tokens.textFieldBackgroundColor}); + ${textFieldTokens.caretColor}: var(${tokens.textFieldCaretColor}); + ${textFieldTokens.placeholderColor}: var(${tokens.textFieldPlaceholderColor}); + ${textFieldTokens.disabledOpacity}: var(${tokens.disabledOpacity}); + + ${textFieldTokens.height}: var(${tokens.textFieldHeight}); + ${textFieldTokens.padding}: var(${tokens.textFieldPadding}); + ${textFieldTokens.borderRadius}: var(${tokens.textFieldBorderRadius}); + + ${textFieldTokens.fontFamily}: var(${tokens.textFieldFontFamily}); + ${textFieldTokens.fontSize}: var(${tokens.textFieldFontSize}); + ${textFieldTokens.fontStyle}: var(${tokens.textFieldFontStyle}); + ${textFieldTokens.fontWeight}: var(${tokens.textFieldFontWeight}); + ${textFieldTokens.letterSpacing}: var(${tokens.textFieldLetterSpacing}); + ${textFieldTokens.lineHeight}: var(${tokens.textFieldLineHeight}); + + &.${classes.firstTextField} > div { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + &.${classes.secondTextField} > div { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + input:focus, &.${classes.textFieldActive} { + ${textFieldTokens.color}: var(${tokens.textFiledFocusColor}); + } +`; + +export const DoubleWrapper = styled.div` + opacity: var(${tokens.disabledOpacity}); +`; + +export const SliderWrapper = styled.div``; diff --git a/packages/plasma-new-hope/src/components/Slider/components/Double/Double.tsx b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.tsx new file mode 100644 index 0000000000..84fe67bdb7 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.tsx @@ -0,0 +1,328 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import type { FC, ChangeEvent, KeyboardEvent, FocusEvent } from 'react'; + +import { SliderBase } from '../SliderBase/SliderBase'; +import { Handle } from '../../ui'; +import type { HandleProps } from '../../ui'; +import { sizeData } from '../../utils'; +import { cx, isNumber } from '../../../../utils'; +import { classes } from '../../Slider.tokens'; + +import { DoubleSliderProps } from './Double.types'; +import { + SliderWrapper, + InputsWrapper, + Label, + LabelContentLeft, + LabelWrapper, + StyledInput, + DoubleWrapper, +} from './Double.styles'; + +function getXCenterHandle(handle: HTMLDivElement) { + const containerX = handle.parentElement?.getBoundingClientRect()?.x || 0; + const handleRect = handle.getBoundingClientRect(); + const handlePosition = handleRect.x; + return handlePosition - containerX; +} + +export const DoubleSlider: FC = ({ + min, + max, + value, + disabled, + label, + labelContentLeft, + size = 'm', + onChangeCommitted, + onChangeTextField, + onBlurTextField, + onKeyDownTextField, + onChange, + ariaLabel, + multipleStepSize = 10, + ...rest +}) => { + const [state, setState] = useState({ + stepSize: 0, + railFillWidth: 0, + railFillXPosition: 0, + xFirstHandle: 0, + xSecondHandle: 0, + firstHandleZIndex: 100, + secondHandleZIndex: 101, + firstValue: value[0], + secondValue: value[1], + }); + const [firstInputActive, setFirstInputActive] = useState(false); + const [secondInputActive, setSecondInputActive] = useState(false); + + const firstHandleRef = useRef(null); + const secondHandleRef = useRef(null); + + const firstHandleValue = useRef(value[0]); + const secondHandleValue = useRef(value[1]); + + const [firstValue, setFirstValue] = useState(value[0]); + const [secondValue, setSecondValue] = useState(value[1]); + + const { stepSize } = state; + + const hasLabelContent = label || labelContentLeft; + const firstInputActiveClass = firstInputActive && !disabled ? classes.textFieldActive : undefined; + const secondInputActiveClass = secondInputActive && !disabled ? classes.textFieldActive : undefined; + + useEffect(() => { + const firstLocalValue = Math.min(Math.max(value[0], min), max) - min; + const secondLocalValue = Math.min(Math.max(value[1], min), max) - min; + + setFirstValue(value[0]); + setSecondValue(value[1]); + + setState((prevState) => ({ + ...prevState, + railFillXPosition: stepSize * firstLocalValue, + railFillWidth: stepSize * secondLocalValue - stepSize * firstLocalValue, + xFirstHandle: stepSize * firstLocalValue, + xSecondHandle: stepSize * secondLocalValue, + })); + }, [value, stepSize, min, max, setFirstValue, setSecondValue]); + + const setStepSize = useCallback( + (newStepSize: number) => { + setState((prevState) => ({ + ...prevState, + stepSize: newStepSize, + })); + }, + [setState], + ); + + const onFirstHandleChange = useCallback>( + (handleValue, data) => { + if (!secondHandleRef?.current) { + return; + } + const newHandleXPosition = data.x; + const secondHandleXPosition = getXCenterHandle(secondHandleRef.current); + const fillWidth = secondHandleXPosition - newHandleXPosition; + + firstHandleValue.current = handleValue; + + setFirstValue(handleValue); + + setState((prevState) => ({ + ...prevState, + firstHandleZIndex: 101, + secondHandleZIndex: 100, + railFillWidth: fillWidth < 0 ? 0 : fillWidth, + railFillXPosition: newHandleXPosition, + })); + if (onChange) { + onChange([handleValue, value[1]]); + } + }, + [onChange, value], + ); + + const onFirstHandleChangeCommitted = useCallback>( + (handleValue, data) => { + setFirstValue(handleValue); + onChangeCommitted && onChangeCommitted([handleValue, value[1]]); + + setState((prevState) => ({ + ...prevState, + firstValue: handleValue, + xFirstHandle: data.lastX, + })); + }, + [onChangeCommitted, value], + ); + + const onFirstTextfieldChange = useCallback( + (event: ChangeEvent) => { + if (!isNumber(event.target.value)) { + return; + } + + const handleValue = Number(event.target.value); + + setFirstValue(handleValue); + onChangeTextField && onChangeTextField([handleValue, secondValue], event); + }, + [isNumber, setFirstValue, secondValue], + ); + + const onFirstTextfieldBlur = useCallback( + (event: FocusEvent) => { + if (!isNumber(event.target.value)) { + return; + } + + const handleValue = Number(event.target.value); + + setFirstValue(handleValue); + onBlurTextField && onBlurTextField([handleValue, secondValue], event); + }, + [isNumber, setSecondValue, onBlurTextField, secondValue], + ); + + const onSecondHandleChange = useCallback>( + (handleValue, data) => { + if (!firstHandleRef?.current) { + return; + } + const firstXHandleXPosition = getXCenterHandle(firstHandleRef.current); + + const newHandleXPosition = data.x; + const fillWidth = newHandleXPosition - firstXHandleXPosition; + + secondHandleValue.current = handleValue; + + setSecondValue(handleValue); + setState((prevState) => ({ + ...prevState, + firstHandleZIndex: 100, + secondHandleZIndex: 101, + railFillWidth: fillWidth < 0 ? 0 : fillWidth, + railFillXPosition: firstXHandleXPosition, + })); + if (onChange) { + onChange([value[0], handleValue]); + } + }, + [onChange, value], + ); + + const onSecondHandleChangeCommitted = useCallback>( + (handleValue, data) => { + onChangeCommitted && onChangeCommitted([value[0], handleValue]); + setSecondValue(handleValue); + setState((prevState) => ({ + ...prevState, + secondValue: handleValue, + xSecondHandle: data.lastX, + })); + }, + [onChangeCommitted, value], + ); + + const onSecondTextfieldChange = useCallback( + (event: ChangeEvent) => { + if (!isNumber(event.target.value)) { + return; + } + const handleValue = Number(event.target.value); + + setSecondValue(handleValue); + onChangeTextField && onChangeTextField([firstValue, handleValue], event); + }, + [isNumber, setSecondValue, onChangeTextField, firstValue], + ); + + const onSecondTextfieldBlur = useCallback( + (event: FocusEvent) => { + if (!isNumber(event.target.value)) { + return; + } + + const handleValue = Number(event.target.value); + + setSecondValue(handleValue); + onBlurTextField && onBlurTextField([firstValue, handleValue], event); + }, + [isNumber, setSecondValue, onBlurTextField, firstValue], + ); + + const onTextfieldKeyDown = useCallback( + (event: ChangeEvent & KeyboardEvent) => { + onKeyDownTextField && onKeyDownTextField([firstValue, secondValue], event); + }, + [[isNumber, setSecondValue, onKeyDownTextField], firstValue, secondValue], + ); + + const [ariaLabelLeft, ariaLabelRight] = ariaLabel || []; + const currentFirstSliderValue = Math.max(state.firstValue, min); + + return ( + + {hasLabelContent && ( + + {labelContentLeft && {labelContentLeft}} + {label && } + + )} + + + setFirstInputActive(true)} + onMouseLeave={() => setFirstInputActive(false)} + /> + setSecondInputActive(true)} + onMouseLeave={() => setSecondInputActive(false)} + /> + + + + + + + + + ); +}; diff --git a/packages/plasma-new-hope/src/components/Slider/components/Double/Double.types.ts b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.types.ts new file mode 100644 index 0000000000..61a9c11a62 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Double/Double.types.ts @@ -0,0 +1,70 @@ +import type { HTMLAttributes, ChangeEvent, KeyboardEvent, FocusEvent } from 'react'; + +import type { SliderBaseProps, SliderInternalProps } from '../SliderBase/SliderBase.types'; + +export interface DoubleSliderProps + extends SliderBaseProps, + SliderInternalProps, + Omit, 'onChange'> { + /** + * Текущее значение + */ + value: number[]; + /** + * Вызывается при отпускании ползунка + */ + onChangeCommitted?: (value: number[]) => void; + /** + * Вызывается при перемещении ползунка + */ + onChange?: (value: number[]) => void; + /** + * Вызывается при изменении TextField + */ + onChangeTextField?: (value: number[], event: ChangeEvent) => void; + /** + * Вызывается при анфокусе TextField + */ + onBlurTextField?: (value: number[], event: FocusEvent) => void; + /** + * Вызывается при нажатии на клавишу в TextField + */ + onKeyDownTextField?: (value: number[], event: KeyboardEvent) => void; + /** + * Расположение значений минимума и максимума интервала. + */ + rangeValuesPlacement?: never; + /** + * Отображать ли текущее значение. + */ + showCurrentValue?: never; + /** + * Отображать ли значения минимума и максимума интервала. + */ + showRangeValues?: never; + /** + * Разница между текущим значением и минимальным, при котором минимальное будет скрыто. + */ + hideMinValueDiff?: never; + /** + * Разница между текущим значением и максимальным, при котором максимальное будет скрыто. + */ + hideMaxValueDiff?: never; + /** + * Расположение подписи. + */ + labelPlacement?: never; + /** + * Ярлык, определяющий назначение ползунка, например «Минимальная цена» [a11y]. + */ + ariaLabel?: string[]; + /** + * Размера увеличенного шага (для клавиш PageUp, PageDown). + * Указывает процентное отношение от максимально возможного значения. + * Указав значение 20 при максимуме в 100, получим 20%. + */ + multipleStepSize?: number; + + view?: string; + size?: 's' | 'm' | 'l'; +} diff --git a/packages/plasma-new-hope/src/components/Slider/components/Single/Single.styles.ts b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.styles.ts new file mode 100644 index 0000000000..d82958cba2 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.styles.ts @@ -0,0 +1,92 @@ +import { styled } from '@linaria/react'; + +import { classes, tokens } from '../../Slider.tokens'; + +export const LabelWrapper = styled.div` + color: var(${tokens.labelColor}); + + display: flex; + gap: var(${tokens.labelWrapperGap}); +`; + +export const LabelContentLeft = styled.div``; + +export const Label = styled.label` + font-family: var(${tokens.labelFontFamily}); + font-size: var(${tokens.labelFontSize}); + font-style: var(${tokens.labelFontStyle}); + font-weight: var(${tokens.labelFontWeight}); + letter-spacing: var(${tokens.labelLetterSpacing}); + line-height: var(${tokens.labelLineHeight}); +`; + +export const StyledRangeValue = styled.span` + color: var(${tokens.rangeValueColor}); + font-family: var(${tokens.rangeValueFontFamily}); + font-size: var(${tokens.rangeValueFontSize}); + font-style: var(${tokens.rangeValueFontStyle}); + font-weight: var(${tokens.rangeValueFontWeight}); + letter-spacing: var(${tokens.rangeValueLetterSpacing}); + line-height: var(${tokens.rangeValueLineHeight}); + + transition: opacity 0.1s ease-in-out; + + &.${classes.hideMinValue}, &.${classes.hideMaxValue} { + opacity: 0; + } + + &.${classes.activeRangeValue} { + color: var(${tokens.labelColor}); + } +`; + +export const SliderBaseWrapper = styled.div` + position: relative; + display: flex; + flex: 1; + + &.${classes.rangeValuesPlacementOuter} { + ${StyledRangeValue} { + position: absolute; + bottom: var(${tokens.rangeValueBottomOffset}); + left: 0; + + &.${classes.maxRangeValue} { + left: unset; + right: 0; + } + } + } + + &.${classes.rangeValuesPlacementInner} { + align-items: center; + + ${StyledRangeValue} { + margin-right: var(${tokens.rangeMinValueMargin}); + + &.${classes.maxRangeValue} { + margin-right: 0; + margin-left: var(${tokens.rangeMaxValueMargin}); + } + } + } +`; + +export const SingleWrapper = styled.div` + display: flex; + opacity: var(${tokens.disabledOpacity}); + + &.${classes.labelPlacementOuter} { + flex-direction: column; + + ${LabelWrapper} { + margin-bottom: var(${tokens.labelWrapperMarginBottom}); + } + } + + &.${classes.labelPlacementInner} { + ${LabelWrapper} { + margin-right: var(${tokens.labelWrapperMarginRight}); + } + } +`; diff --git a/packages/plasma-new-hope/src/components/Slider/components/Single/Single.tsx b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.tsx new file mode 100644 index 0000000000..3526b8f91e --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.tsx @@ -0,0 +1,183 @@ +import React, { useCallback, useEffect, useState, useRef } from 'react'; +import type { FC } from 'react'; + +import { SliderBase } from '../SliderBase/SliderBase'; +import { Handle } from '../../ui'; +import { sizeData } from '../../utils'; +import type { HandleProps } from '../../ui'; +import { cx, isNumber } from '../../../../utils'; +import { classes } from '../../Slider.tokens'; + +import type { SingleSliderProps } from './Single.types'; +import { + Label, + LabelContentLeft, + LabelWrapper, + SingleWrapper, + SliderBaseWrapper, + StyledRangeValue, +} from './Single.styles'; + +export const SingleSlider: FC = ({ + min, + max, + value, + disabled, + onChangeCommitted, + onChange, + ariaLabel, + label, + labelContentLeft, + showRangeValues, + showCurrentValue, + hideMinValueDiff, + hideMaxValueDiff, + labelPlacement = 'outer', + rangeValuesPlacement = 'outer', + multipleStepSize = 10, + size = 'm', + ...rest +}) => { + const [state, setState] = useState({ + xHandle: 0, + stepSize: 0, + railFillWidth: 0, + }); + + const { stepSize } = state; + + const hasLabelContent = label || labelContentLeft; + const labelPlacementClass = labelPlacement === 'outer' ? classes.labelPlacementOuter : classes.labelPlacementInner; + const rangeValuesPlacementClass = + rangeValuesPlacement === 'outer' ? classes.rangeValuesPlacementOuter : classes.rangeValuesPlacementInner; + const hideMinValueDiffClass = hideMinValueDiff && value - min <= hideMinValueDiff ? classes.hideMinValue : ''; + const hideMaxValueDiffClass = hideMaxValueDiff && max - value <= hideMaxValueDiff ? classes.hideMaxValue : ''; + + const startLabelRef = useRef(null); + const endLabelRef = useRef(null); + + const [startOffset, setStartOffset] = useState(0); + const [endOffset, setEndOffset] = useState(0); + + const [dragValue, setDragValue] = useState(value); + + const activeFirstValue = dragValue === min ? classes.activeRangeValue : undefined; + const activeSecondValue = dragValue === max ? classes.activeRangeValue : undefined; + + useEffect(() => { + const localValue = Math.min(Math.max(value, min), max) - min; + + if (rangeValuesPlacement === 'outer') { + const startWidth = startLabelRef.current?.offsetWidth; + if (isNumber(startWidth)) { + setStartOffset(Number(startWidth)); + } + + const endWidth = endLabelRef.current?.offsetWidth; + if (isNumber(endWidth)) { + setEndOffset(Number(endWidth)); + } + } else { + setStartOffset(1); + setEndOffset(1); + } + + setState((prevState) => ({ + ...prevState, + xHandle: stepSize * localValue, + railFillWidth: stepSize * localValue, + })); + }, [value, labelPlacement, stepSize, rangeValuesPlacement, min, max, setStartOffset, setEndOffset]); + + const setStepSize = useCallback((newStepSize: number) => { + setState((prevState) => ({ + ...prevState, + stepSize: newStepSize, + })); + }, []); + + const onHandleChange = useCallback>( + (handleValue, data) => { + const newHandleXPosition = data.x; + setState((prevState) => ({ + ...prevState, + railFillWidth: newHandleXPosition, + })); + + if (onChange) { + onChange(handleValue); + } + + setDragValue(handleValue); + }, + [onChange, setDragValue], + ); + + const onHandleChangeCommitted = useCallback>( + (handleValue, data) => { + onChangeCommitted && onChangeCommitted(handleValue); + setState((prevState) => ({ + ...prevState, + xHandle: data.lastX, + railFillWidth: data.lastX, + })); + + setDragValue(handleValue); + }, + [onChangeCommitted, setDragValue], + ); + + return ( + + {hasLabelContent && ( + + {labelContentLeft && {labelContentLeft}} + {label && } + + )} + + {showRangeValues && ( + + {min} + + )} + + + + {showRangeValues && ( + + {max} + + )} + + + ); +}; diff --git a/packages/plasma-new-hope/src/components/Slider/components/Single/Single.types.ts b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.types.ts new file mode 100644 index 0000000000..633e4158e8 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/Single/Single.types.ts @@ -0,0 +1,60 @@ +import type { HTMLAttributes } from 'react'; + +import type { SliderBaseProps, SliderInternalProps } from '../SliderBase/SliderBase.types'; + +export interface SingleSliderProps + extends SliderBaseProps, + SliderInternalProps, + Omit, 'onChange'> { + /** + * Текущее знaчение + */ + value: number; + /** + * Вызывается при отпускании ползунка + */ + onChangeCommitted?: (value: number) => void; + /** + * Вызывается при перемещении ползунка + */ + onChange?: (value: number) => void; + /** + * Ярлык, определяющий назначение ползунка, например «Минимальная цена» [a11y]. + */ + ariaLabel?: string; + /** + * Отображать ли текущее значение. + */ + showCurrentValue?: boolean; + /** + * Отображать ли значения минимума и максимума интервала. + */ + showRangeValues?: boolean; + /** + * Разница между текущим значением и минимальным, при котором минимальное будет скрыто. + */ + hideMinValueDiff?: number; + /** + * Разница между текущим значением и максимальным, при котором максимальное будет скрыто. + */ + hideMaxValueDiff?: number; + /** + * Расположение значений минимума и максимума интервала. + * @default `outer` + */ + rangeValuesPlacement?: 'inner' | 'outer'; + /** + * Расположение подписи. + * @default `outer` + */ + labelPlacement?: 'inner' | 'outer'; + /** + * Размера увеличенного шага (для клавиш PageUp, PageDown). + * Указывает процентное отношение от максимально возможного значения. + * Указав значение 20 при максимуме в 100, получим 20%. + */ + multipleStepSize?: number; + + view?: string; + size?: 's' | 'm' | 'l'; +} diff --git a/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.styles.ts b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.styles.ts new file mode 100644 index 0000000000..4ec9361bc8 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.styles.ts @@ -0,0 +1,36 @@ +import { styled } from '@linaria/react'; + +import { tokens } from '../../Slider.tokens'; + +export const Slider = styled.div` + flex: 1; + position: relative; + user-select: none; + height: var(${tokens.height}); +`; + +export const RailWrap = styled.div` + height: 100%; +`; + +export const Rail = styled.div` + position: relative; + top: 50%; + + height: var(${tokens.railHeight}); + + border-radius: var(${tokens.railBorderRadius}); + background-color: var(${tokens.railBackgroundColor}); + + overflow: hidden; + transform: translateY(-50%); +`; + +export const Fill = styled.div` + position: absolute; + height: 100%; + top: 0; + left: 0; + background: var(${tokens.fillColor}); + width: 0; +`; diff --git a/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.tsx b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.tsx new file mode 100644 index 0000000000..42b839c21b --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.tsx @@ -0,0 +1,87 @@ +import React, { PropsWithChildren, useCallback, useRef, MouseEventHandler, useEffect } from 'react'; +import { DraggableData } from 'react-draggable'; + +import { useIsomorphicLayoutEffect } from '../../../../hooks'; + +import type { SliderViewProps } from './SliderBase.types'; +import { Fill, Rail, RailWrap, Slider } from './SliderBase.styles'; + +export const SliderBase: React.FC> = ({ + max, + min, + setStepSize, + railFillWidth, + children, + railFillXPosition = 0, + disabled, + labelPlacement, + rangeValuesPlacement, + onChange, + settings = {}, +}) => { + const { indent = 0.75, fontSizeMultiplier = 16 } = settings; + + const ref = useRef(null); + const gap = indent * fontSizeMultiplier * 2; + + useEffect(() => { + const resizeHandler = () => { + if (ref.current) { + const railSize = ref.current.offsetWidth - gap; + const totalSteps = max - min; + + setStepSize(railSize / totalSteps); + } + }; + + resizeHandler(); + }, [labelPlacement, rangeValuesPlacement, ref.current]); + + const onHandleChange: MouseEventHandler = useCallback( + (e) => { + if (!onChange || disabled) { + return; + } + + const { x, width } = e.currentTarget.getBoundingClientRect(); + + const lastX = e.clientX - x; + + const position = min + (lastX / (width - gap)) * (max - min); + const result = Math.max(min, Math.min(max, position)); + + onChange(result, { lastX } as DraggableData); + }, + [onChange, disabled, min, gap, max, settings], + ); + + useIsomorphicLayoutEffect(() => { + const resizeHandler = () => { + if (ref.current) { + const railSize = ref.current.offsetWidth - gap; + const totalSteps = max - min; + + setStepSize(railSize / totalSteps); + } + }; + + resizeHandler(); + window.addEventListener('resize', resizeHandler); + + return () => window.removeEventListener('resize', resizeHandler); + }, [min, max, setStepSize, ref.current, gap, labelPlacement, rangeValuesPlacement]); + + const fillStyle = { left: `${railFillXPosition}px`, width: `${railFillWidth}px` }; + + return ( + + + + {children} + + ); +}; diff --git a/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.types.ts b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.types.ts new file mode 100644 index 0000000000..fe4dd68e1c --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/SliderBase/SliderBase.types.ts @@ -0,0 +1,48 @@ +import type { ReactNode } from 'react'; +import type { DraggableData } from 'react-draggable'; + +export type SliderSettings = Partial<{ + indent?: number; + fontSizeMultiplier?: number; + backgroundColor?: string; + fillColor?: string; +}>; + +export interface SliderBaseProps { + /** + * Минимальное значение + */ + min: number; + /** + * Максимальное значение + */ + max: number; + /** + * подпись к слайдеру + */ + label?: string; + /** + * Слот под контент слева от подписи (например иконку) + */ + labelContentLeft?: ReactNode; + /** + * Компонент неактивен + */ + disabled?: boolean; + labelPlacement?: string; + rangeValuesPlacement?: string; +} + +export interface SliderInternalProps { + /** + * Настройки внешнего вида slider + */ + settings?: SliderSettings; +} + +export interface SliderViewProps extends SliderBaseProps, SliderInternalProps { + railFillWidth: number; + setStepSize(stepSize: number): void; + railFillXPosition?: number; + onChange?(value: number, data: DraggableData): void; +} diff --git a/packages/plasma-new-hope/src/components/Slider/components/index.ts b/packages/plasma-new-hope/src/components/Slider/components/index.ts new file mode 100644 index 0000000000..5901209024 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/components/index.ts @@ -0,0 +1,6 @@ +export * from './Single/Single'; +export * from './Double/Double'; + +export type { SingleSliderProps } from './Single/Single.types'; +export type { DoubleSliderProps } from './Double/Double.types'; +export type { SliderInternalProps, SliderSettings } from './SliderBase/SliderBase.types'; diff --git a/packages/plasma-new-hope/src/components/Slider/index.ts b/packages/plasma-new-hope/src/components/Slider/index.ts new file mode 100644 index 0000000000..c4422a3bf0 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/index.ts @@ -0,0 +1,7 @@ +export { sliderConfig, sliderRoot } from './Slider'; +export { tokens as sliderTokens } from './Slider.tokens'; + +export { ThumbBase } from './ui'; + +export type { SliderProps } from './Slider.types'; +export type { SliderSettings, SingleSliderProps, DoubleSliderProps } from './components'; diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.styles.ts b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.styles.ts new file mode 100644 index 0000000000..9e46a7b619 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.styles.ts @@ -0,0 +1,28 @@ +import { styled } from '@linaria/react'; + +import { tokens } from '../../Slider.tokens'; + +export const HandleStyled = styled.div` + cursor: pointer; + position: absolute; + z-index: 1; + top: 0; + left: 0; +`; + +export const StyledValue = styled.span` + position: absolute; + z-index: 1; + top: var(${tokens.currentValueTopOffset}); + text-align: center; + width: 100%; + margin-left: -0.125rem; + display: flex; + justify-content: center; + font-family: var(${tokens.currentValueFontFamily}); + font-size: var(${tokens.currentValueFontSize}); + font-style: var(${tokens.currentValueFontStyle}); + font-weight: var(${tokens.currentValueFontWeight}); + letter-spacing: var(${tokens.currentValueLetterSpacing}); + line-height: var(${tokens.currentValueLineHeight}); +`; diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.tsx b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.tsx new file mode 100644 index 0000000000..69be8f3c56 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.tsx @@ -0,0 +1,185 @@ +import React, { useState, useRef, useCallback, forwardRef, KeyboardEvent } from 'react'; +import Draggable, { DraggableEventHandler } from 'react-draggable'; +import type { DraggableData } from 'react-draggable'; + +import { getSliderThumbValue, getOffsets } from '../../utils'; +import { Thumb } from '../Thumb/Thumb'; + +import type { HandleProps } from './Handle.types'; +import { HandleStyled, StyledValue } from './Handle.styles'; + +// TODO: PLASMA-1707 +declare module 'react-draggable' { + export interface DraggableProps { + children: React.ReactNode; + } +} + +const KeyboardSupport = { + PageUp: 33, + PageDown: 34, + End: 35, + Home: 36, + ArrowLeft: 37, + ArrowUp: 38, + ArrowRight: 39, + ArrowDown: 40, +}; + +export const Handle = forwardRef( + ( + { + stepSize, + onChangeCommitted, + onChange, + xPosition = 0, + min, + max, + bounds = [], + zIndex, + disabled, + side, + showCurrentValue = false, + startOffset = 0, + endOffset = 0, + ...rest + }, + ref, + ) => { + const lastOnChangeValue = useRef(); + const currentSliderValue = lastOnChangeValue?.current ?? rest.value; + + const [offsetLeft, offsetRight] = getOffsets(ref, side); + + const [leftValueBound, rightValueBound] = bounds; + const leftPositionBound = leftValueBound ? (leftValueBound - min) * stepSize : null; + const rightPositionBound = rightValueBound ? (rightValueBound - min) * stepSize : null; + + const position = typeof xPosition === 'number' ? { x: xPosition, y: 0 } : undefined; + const tabIndex = disabled ? -1 : 0; + + const [positionX, setPositionX] = useState(position?.x ?? 0); + + const computedBounds = { + left: (leftPositionBound ?? 0) + offsetLeft, + right: (rightPositionBound ?? stepSize * (max - min)) - offsetRight, + }; + + const showCurrentValueCondition = + showCurrentValue && positionX >= startOffset && positionX <= max * stepSize - endOffset; + + const onDrag = useCallback( + (_, data) => { + const newValue = getSliderThumbValue(data.x, stepSize, min, max); + if (lastOnChangeValue.current !== newValue) { + onChange?.(newValue, data); + setPositionX(data.x); + lastOnChangeValue.current = newValue; + } + }, + [onChange, setPositionX, stepSize, min, max], + ); + + const onStop = useCallback( + (_, data) => { + const newValue = getSliderThumbValue(data.x, stepSize, min, max); + setPositionX(data.x); + onChangeCommitted && onChangeCommitted(newValue, data); + }, + [onChangeCommitted, setPositionX, stepSize, min, max], + ); + + const onKeyPress = useCallback( + (event: KeyboardEvent) => { + event.persist(); + + const { keyCode, target } = event; + + if (!Object.values(KeyboardSupport).includes(keyCode)) { + return; + } + + const { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Home, End, PageDown, PageUp } = KeyboardSupport; + + const computedMultipleSteps = stepSize * ((rest.multipleStepSize / 100) * max); + + const data: DraggableData = { + x: 0, + deltaX: stepSize, + lastX: xPosition, + y: 0, + deltaY: 0, + lastY: 0, + node: target as HTMLDivElement, + }; + + switch (keyCode) { + case ArrowUp: + case ArrowRight: + data.x = xPosition + stepSize; + break; + case ArrowDown: + case ArrowLeft: + data.x = xPosition - stepSize; + data.deltaX = -stepSize; + break; + case PageUp: + data.x = xPosition + computedMultipleSteps; + data.deltaX = computedMultipleSteps; + break; + case PageDown: + data.x = xPosition - computedMultipleSteps; + data.deltaX = -computedMultipleSteps; + break; + case End: + data.x = max * stepSize; + break; + case Home: + data.x = 0; + break; + default: + data.x = 0; + } + + const { left, right } = computedBounds; + + /* + * INFO: Находим значение в диапазоне между указанными левой и правой границами. + * Необходимо для правильного расчета положения SliderThumb. + * см. функция clamp + */ + const boundedValue = Math.max(Math.min(right, data.x), left); + + const computedValue = getSliderThumbValue(boundedValue, stepSize, min, max); + lastOnChangeValue.current = computedValue; + + onChangeCommitted && onChangeCommitted(computedValue, data); + }, + [onChangeCommitted, bounds, stepSize, rest.multipleStepSize, min, max, xPosition], + ); + + return ( + + + + {showCurrentValueCondition && {currentSliderValue}} + + + ); + }, +); diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.types.ts b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.types.ts new file mode 100644 index 0000000000..55e430ff2a --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Handle/Handle.types.ts @@ -0,0 +1,24 @@ +import type { DraggableData } from 'react-draggable'; + +export interface HandleProps { + stepSize: number; + min: number; + max: number; + multipleStepSize: number; + onChangeCommitted?(value: number, data: DraggableData): void; + side?: 'left' | 'right'; + bounds?: number[]; + xPosition?: number; + zIndex?: number; + disabled?: boolean; + value?: number; + ariaLabel?: string; + ariaValueMin?: number; + hasHoverAnimation?: boolean; + showCurrentValue?: boolean; + startOffset?: number; + endOffset?: number; + onChange?(value: number, data: DraggableData): void; + onMouseEnter?(): void; + onMouseLeave?(): void; +} diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.styles.ts b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.styles.ts new file mode 100644 index 0000000000..85be9a8e84 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.styles.ts @@ -0,0 +1,47 @@ +import { styled } from '@linaria/react'; + +import { addFocus } from '../../../../mixins'; +import { tokens } from '../../Slider.tokens'; + +export const ThumbBase = styled.div<{ disabled?: boolean }>` + width: var(${tokens.thumbSize}); + height: var(${tokens.thumbSize}); + position: relative; + left: -0.125rem; + top: -0.125rem; + border-radius: 50%; + box-sizing: border-box; + background: var(${tokens.thumbBackgroundColor}); + margin: 0.125rem; + transition: border-color 0.1s ease-in-out; + + &:after { + background: var(${tokens.thumbBorderColor}); + margin: -0.125rem; + content: ''; + position: absolute; + inset: 0; + z-index: -1; + border-radius: inherit; + } + + &:not([disabled]):hover:after, + &:not([disabled]):active:after { + background: var(${tokens.thumbFocusBorderColor}); + } + + &[disabled] { + cursor: not-allowed; + } + + &:focus { + outline: none; + } + + ${addFocus({ + outlineOffset: '0.125rem', + outlineSize: '0.125rem', + outlineRadius: '50%', + outlineColor: `var(${tokens.thumbFocusBorderColor})`, + })} +`; diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.tsx b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.tsx new file mode 100644 index 0000000000..11bb6898db --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import type { ThumbProps } from './Thumb.types'; +import { ThumbBase } from './Thumb.styles'; + +export const Thumb = ({ min, max, value, ariaValueMin = min, ariaLabel, disabled, ...rest }: ThumbProps) => { + return ( + + ); +}; diff --git a/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.types.ts b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.types.ts new file mode 100644 index 0000000000..7afd741c4e --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/Thumb/Thumb.types.ts @@ -0,0 +1,11 @@ +export interface ThumbProps { + min: number; + max: number; + multipleStepSize: number; + tabIndex: number; + value?: number; + ariaLabel?: string; + ariaValueMin?: number; + hasHoverAnimation?: boolean; + disabled?: boolean; +} diff --git a/packages/plasma-new-hope/src/components/Slider/ui/index.ts b/packages/plasma-new-hope/src/components/Slider/ui/index.ts new file mode 100644 index 0000000000..3b3067aab0 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/ui/index.ts @@ -0,0 +1,7 @@ +export * from './Handle/Handle'; +export * from './Thumb/Thumb'; + +export { ThumbBase } from './Thumb/Thumb.styles'; + +export * from './Handle/Handle.types'; +export * from './Thumb/Thumb.types'; diff --git a/packages/plasma-new-hope/src/components/Slider/utils/index.ts b/packages/plasma-new-hope/src/components/Slider/utils/index.ts new file mode 100644 index 0000000000..fd746e9dda --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/utils/index.ts @@ -0,0 +1,58 @@ +import { MutableRefObject } from 'react'; + +/** + * Расчитать значение слайдера с учетом его координат и шага изменений. + * @param {number} handleCenterXRelative + * @param {number} stepSize + * @param {number} min + * @param {number} max + * @return {number} + */ +export function getSliderThumbValue(handleCenterXRelative: number, stepSize: number, min: number, max: number) { + const newValue = Math.round(handleCenterXRelative / stepSize) + min; + + return Math.min(Math.max(newValue, min), max); +} + +/** + * Расчитывает значение отступа слайдера на основе его положения (справа, слева) на отрезке слайдера. + * Значение используется для правильного расчета ограничения движения слайдера. + * @param ref + * @param {'left' | 'right'} side + * @return Array + */ +export function getOffsets( + ref: ((instance: HTMLDivElement | null) => void) | MutableRefObject | null, + side?: 'left' | 'right', +): number[] { + if (!ref || !('current' in ref) || !ref.current || !side) { + return [0, 0]; + } + + const size = ref.current.clientWidth; + + if (side === 'left') { + return [0, size]; + } + + if (side === 'right') { + return [size, 0]; + } + + return [0, 0]; +} + +export const sizeData = { + s: { + indent: 0.5, + fontSizeMultiplier: 16, + }, + m: { + indent: 0.75, + fontSizeMultiplier: 16, + }, + l: { + indent: 0.75, + fontSizeMultiplier: 16, + }, +}; diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_disabled/base.tsx b/packages/plasma-new-hope/src/components/Slider/variations/_disabled/base.tsx new file mode 100644 index 0000000000..cd585b76c4 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/variations/_disabled/base.tsx @@ -0,0 +1,3 @@ +import { css } from '@linaria/core'; + +export const base = css``; diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_disabled/tokens.json b/packages/plasma-new-hope/src/components/Slider/variations/_disabled/tokens.json new file mode 100644 index 0000000000..66b76487b8 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/variations/_disabled/tokens.json @@ -0,0 +1,4 @@ +{ + "type": "boolean", + "tokens": ["--plasma-slider-disabled-opacity"] +} diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_size/base.tsx b/packages/plasma-new-hope/src/components/Slider/variations/_size/base.tsx new file mode 100644 index 0000000000..cd585b76c4 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/variations/_size/base.tsx @@ -0,0 +1,3 @@ +import { css } from '@linaria/core'; + +export const base = css``; diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_size/tokens.json b/packages/plasma-new-hope/src/components/Slider/variations/_size/tokens.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_view/base.tsx b/packages/plasma-new-hope/src/components/Slider/variations/_view/base.tsx new file mode 100644 index 0000000000..cd585b76c4 --- /dev/null +++ b/packages/plasma-new-hope/src/components/Slider/variations/_view/base.tsx @@ -0,0 +1,3 @@ +import { css } from '@linaria/core'; + +export const base = css``; diff --git a/packages/plasma-new-hope/src/components/Slider/variations/_view/tokens.json b/packages/plasma-new-hope/src/components/Slider/variations/_view/tokens.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/plasma-new-hope/src/components/TextField/TextField.tsx b/packages/plasma-new-hope/src/components/TextField/TextField.tsx index b2f4e95f5f..fad5899873 100644 --- a/packages/plasma-new-hope/src/components/TextField/TextField.tsx +++ b/packages/plasma-new-hope/src/components/TextField/TextField.tsx @@ -1,5 +1,5 @@ import React, { forwardRef, useEffect, useRef, useState } from 'react'; -import type { ChangeEventHandler } from 'react'; +import type { ChangeEventHandler, KeyboardEvent, ChangeEvent } from 'react'; import { safeUseId, useForkRef } from '@salutejs/plasma-core'; import { css } from '@linaria/core'; @@ -37,6 +37,8 @@ export const textFieldRoot = (Root: RootProps) = ( { id, + className, + style, // layout contentLeft, @@ -60,6 +62,7 @@ export const textFieldRoot = (Root: RootProps) = onChange, onChangeChips, onSearch, + onKeyDown, ...rest }, @@ -144,6 +147,11 @@ export const textFieldRoot = (Root: RootProps) = } }; + const handleOnKeyDown = (event: ChangeEvent & KeyboardEvent) => { + handleInputKeydown(event); + onKeyDown && onKeyDown(event); + }; + useEffect(() => { if (!isChipEnumeration && !values?.length) { return; @@ -166,6 +174,8 @@ export const textFieldRoot = (Root: RootProps) = readOnly={!disabled && readOnly} labelPlacement={innerLabelPlacementValue} onClick={handleInputFocus} + className={className} + style={style} > {labelInside || (innerLabelValue && ( @@ -211,7 +221,7 @@ export const textFieldRoot = (Root: RootProps) = disabled={disabled} readOnly={!disabled && readOnly} onChange={handleChange} - onKeyDown={handleInputKeydown} + onKeyDown={handleOnKeyDown} /> {labelInside && (