From f921b2715575dd41d97fbdb9f69ad648cbb637ae Mon Sep 17 00:00:00 2001 From: David <33458145+davidmcpowell@users.noreply.github.com> Date: Mon, 11 Aug 2025 14:14:13 +0100 Subject: [PATCH] Merge pull request #27715 from overleaf/dp-rail-overflow-2 Add new editor rail overflow menu GitOrigin-RevId: f93da19a2687c099ece4509c22a374a47e94f5ad --- ...alSymbolsRoundedUnfilledPartialSlice.woff2 | Bin 5300 -> 5340 bytes .../material-symbols/unfilled-symbols.mjs | 1 + .../components/rail/rail-action-element.tsx | 8 ++- .../rail/rail-overflow-dropdown.tsx | 32 +++++++++++ .../ide-redesign/components/rail/rail.tsx | 53 +++++++++++++----- .../ide-redesign/hooks/use-rail-overflow.tsx | 35 ++++++++++++ .../stylesheets/pages/editor/rail.scss | 20 ++++++- 7 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 services/web/frontend/js/features/ide-redesign/components/rail/rail-overflow-dropdown.tsx create mode 100644 services/web/frontend/js/features/ide-redesign/hooks/use-rail-overflow.tsx diff --git a/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 b/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 index 34f72414102f6e5f55915f7a1239accb71c875bd..1e0374e8a35c39f521475f1f20cb063d1f7e5463 100644 GIT binary patch literal 5340 zcmV<26eH_*Pew8T0RR9102JH+4gdfE04&S^02G7(0RR9100000000000000000000 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 ufz-dB0I5ht9K0Za05J?Ou?$kctI(+GawlN literal 5300 zcmV;l6ie%OPew8T0RR9102H(U4gdfE04zWN02EsQ0RR9100000000000000000000 z0000Si#7&eKT}jeRAK;wJ`o5Cy==5f3w8hjHUcCAb_5^=g$@TG3EbdB5GOlD7JG7D+8 zJ$du8MAL7?-ELtj!Byi;-A{1!fG_AusSAwjncKK z(SAS*<~@2es7uQx<7VN~pu~V71({CtT68H>Ev;}d2w8x+{MO4z#)&bGNrM`71{4|6 zqR2SOOOS{;WI#*Q6ID=IhX5Z7+*CSL3GvZ5lxwl+1r&2ghq6+!vG@g)g2d#wZ&v72VwTpG(b599hAqRkF^*sxw=y|gGN^m(ds+jq6rLn$df1qODP7&-ydkh+J!#WP z`O%?$=xJg^4`~K&Ya^K^hQ#KbhIV8T$($fTi4Qj9i58ji0v)TXE0KB?2&tRp?onPB zH=(iUMze$>B)ICSy$ZLq<&HaU$?F7vKC1?!dqAzSuS;)>^1AZ69?*)Dff~fwM*&tt zZn5=t+f}*7EqB>?Ga(Qso^$Mi+^0Q{gQ*0?!5HyrSC5Nc-f=N z-d^_W^7M*>R(!JZ*p*jA*=Wb;#OT!M%IJpZj_9%I+35Lbe)QjLVm6%pW%l2%xBFqY zA9wlj>>qFcZQb9_`t#Y*2nbl6138#uIb|^qy}O-1)8i?@d6j?mpA|gw?CNOF==ITS zqgP?(zM0)-n(&#NeqidYsk^6kp4xo!gvp&IgNfh9pB&#de_Q_6oRR%Fdmm&k&YqP$ zC3{$Q`|RP_O|y2^&U}?=XHw~Bz2_3oCGJg}XUzqDX9R};K+N`nMcR!;AFl!R;oJc_ zIyoE!ab}qIOfedfD52}zdruqt39yfX_|2$(gKKC;&o$IDEa8m;GP3H+l2GFagi7aU zXy_MUeqKoh6)*9bNxB{FIjD-FC`HS4t@t3}x~Z(=S-P%zp69ua?>LUT5yI;$J8obY zzUrxyo|o}bsjTOC$2iyZ$8rJOr)Q

0n%qX=c)OGalL{yI3p^?V+^jd0V#RUVmS| zZCRFW+jdFsa~$g2e!x7iskosCAH3fv4i4_4)TDb%bHM2HY}&&3SYxWn1k%0>i*j$A`3t! zG>ixlv3pmn%Bl43FBIbEx6hA7DGI%ynFXo`GN)liME7w!{0a*4Yjo6?#1LOR<#aO2 zmJ)o*!#8rjhEjq~sfN6oN*|-j1(0c+Z%AoHQr4sS^dNYMa(|Zz_~ zKTkfI5MGcj6G(-Fr9K(gx=8soTIx$;z?pSRNdc2GrIL=ul^armqj}mxP$H_&qdVV! zHI-fxmRKZQU&vdO9={X`H&$hyN-s#lQY74a4P+dg`5V=r>rqpJPQX?k?w}AFA|B2U zz+!|(R|6KSSHK)=4OD>?C1zNqgUsrEU_eLPX2#G48zuFDs{w3rFL(>s{xBX^E^7Hd zfGjH8AIB<{uo@)2q?VX=EkRZ0n{l}Y9Z@Aq>9$4{HF8?3NC@UKgF!ttNI8x4^`!L3 z_1%vuE%S5+6{fzI2E8tttE@rIx*=Up45z&061w}i* zEIv69nBi9dmioE_JNlAnQa*K6ZFH^wUZt|%f}nwG1UmRcLF^O6Ll)Xu8h zSd=D$M3z(K`f==mK9t??5?LNB3bf6L`f)l^d_k)$3Tq6@(-c+gVk+8O4ZFX2J`a)^ zREY^=b>euKALa0dB@MF+Q{umw(Yh5-=2Ug6p`!v03Q&9zR14r-^}pVJ*1ENBeLkjk z?+=6;uh5}sc}5v;E#OQW&@*aw1Y@b$NR>M=jz%;evn<#u#f zo2NEdHd(qeo^s)#yW%M~K8hEtezJ>2O?Uo}{kV6~KN!p`fSljJ53qKACZOztY+ta? zpPVIPZav%2Tiw(A?S}AJ1DHvNgv64jHMPg5<=V{eIH5n|v*r(bZY*!)+~`G}$Yc-S zfeoj@8#T0%$+Whlp^*2o`jTi@c4hLHQFUD2`FZ!+(mKZ8|BzacW%36`4Hyf8lpr&W z>#iY!Vs~EvrakBM|%{l(smSga|@VYY1fIGqoYA}TSKr4CJYhNun29Wr|}8m z+{dp6#6XR}k>hxBtllH-q{k|>dV+4(uz=6vjshC=Il5h&2y-w#F+!aSg&Dcxz=HE` zqllWCF0@D!;)FQ=*($$=qadfTAoD!m^U=+S$Z1q_c(;2R5%Z0t7}im11czJ8vTWiZ zyzV2vA0O~Xab!F0980d5%H5Gllpkz!5}r^sqpbh2blY6+)sX!;Ny zKm=aYizcG=T)+B`(lT-}fTn$rdR}La_#L^ma7+G{g631Fx8$8(Qm`dI=f6BH@Yh2c z-nPUD3?s0$dwEWzS+4!(+?KZ?4W-K4001Qb;2t?s*!ko4MoQe?``X^U(3rKGX0(oqp$m)zL!-yG}a`I&5 z`kYcZ{yQ$0Dko3&KO2UakuXU#TSYh(3yX&Zixq_p4TbPaOGTvGWMb?Y24_q+Or%Ic z#^mM2c*g;c^jw_5xvn1ONaxSG!%Onw9Dlxhh>Wj;iyB>Imr3*R2Za zjs}R4_a*RoF?Ln}pOPH`fS6lijKDf?%+sl%{!ilSy3kLGhG2>cZcr$L>nW-sSfQ-X zwy9Stf*U;b>yza>cb3oRDf9ngE8^nSd{F&W=A^1PY~3w5;E#X6C0 zwvDJ%2+_gXKwbPw)2(au7HQH}h|%{z8V>I=e8QJb#`N8w96y##ytSXfH8oEzXY3!z zk<|Qldr(AER+HwN-l-rB|6U|@a*{6kJ8fVjR~MzV#**+T-evxf}pv|0ebJ|>o( z0d$}=ysE-QfSGaGe-a>A9L7FLoIF{aXJIiV<3fgwg@s%3sZ&G(I}{_3x8MRe_R71g zlqe}J9lN>&8~{ViPJiqp-+EF~z&24{*Fj?%%E=huZ$5~JRyh9!c8j)wloSfmP-bEo zuVqo!n*i8tO;d+F}m-XnO0e8BL3-bStI_|an85wK33WWO+C*>29VVxkdPz+ z($N1}hqG*k^L03p&&{T(H2ZSorbyu+I=jaN_5~+z8I1#Vgo6i(1QsiS0F+&j-bnRr zQ2|R6uxg}!!0A{>!*351ibhSEnurqxCy1sd`!^IxzbUfd);~rgQq<)!r0Zte zvJ-~PHbs?=nbXlRXMMggQKcp~lB;pg^vhYeFvr`0pL^!N5G3Klp0Ass-Mrt>wC3L! zDtr8SE7p|U=j@a=el6e5@?GyQXRf= zw)dYdl*kuq_8CXpSXtSOHty48f7qVhkF)jdpwL9$=^xTbulPqBoM5M0nj2-`E4H$r zqtnav^~=-gXbZ7bZgsbZ-WY^cW*LTzh-snoZxY1y_-wF>BrNI%gFA)9lX))4+{1Ptl zDkCcz6mxUjA}=yUy*uoL*l1a(=7Mt-qX~r;Ogyx1h6dPygun z-F=HXi}&<`^fNsD(kRL|Ez`3?--lDn;bI4Uva*J~qdBmgPVu6os&hb)lqW46&l^LT;=@AAWY9>xO)TKss zWb}x7Ms8+Xnr>|v>dEiPi0r6Kopiv>$p~r4Uy|Ezz#jV^YL9#qt;Q*5_jut zS-M33r)cM0*Od41f`Xa)-jq{u@BYEXr0v?2|SXhjXmsC5O%I(IiJkbq`L zP>u@3qsHr6iWErD%9~MBZ{#d=fki1Ag3()$i3YTxzBVoYYXo5G?#T4@DzwF>1kK28 zDz}h|2Gm0^ZN7Xz1S3yRK&B@kX#&zSfd%i!oX0|E#TMF0~wK@4~WT6m!C57c7{-m void + hide?: boolean } type RailDropdown = { @@ -20,6 +21,7 @@ type RailDropdown = { icon: AvailableUnfilledIcon title: string dropdown: ReactElement + hide?: boolean } export type RailAction = RailDropdown | RailActionButton @@ -31,6 +33,10 @@ export default function RailActionElement({ action }: { action: RailAction }) { } }, [action]) + if (action.hide) { + return null + } + if ('dropdown' in action) { return ( @@ -41,7 +47,7 @@ export default function RailActionElement({ action }: { action: RailAction }) { > + {tabs + .filter(({ hide }) => !hide) + .map(({ icon, key, indicator, title, disabled }) => ( + + ))} + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx b/services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx index 4cf0c4bd14..de8823d435 100644 --- a/services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/rail/rail.tsx @@ -29,6 +29,8 @@ import { RailElement } from '../../utils/rail-types' import RailPanel from './rail-panel' import RailResizeHandle from './rail-resize-handle' import RailModals from './rail-modals' +import RailOverflowDropdown from './rail-overflow-dropdown' +import useRailOverflow from '../../hooks/use-rail-overflow' export const RailLayout = () => { const { sendEvent } = useEditorAnalytics() @@ -166,6 +168,25 @@ export const RailLayout = () => { const isReviewPanelOpen = selectedTab === 'review-panel' + const { tabsInRail, tabsInOverflow, tabWrapperRef } = + useRailOverflow(railTabs) + + const moreOptionsAction: RailAction = useMemo(() => { + return { + key: 'more-options', + icon: 'more_vert', + title: t('more_options'), + hide: tabsInOverflow.length === 0, + dropdown: ( + + ), + } + }, [t, isOpen, selectedTab, tabsInOverflow]) + return ( { aria-label={t('files_collaboration_integrations_logs')} >