From b5c11370d64267772ffa111a123c1a94444abe81 Mon Sep 17 00:00:00 2001 From: David <33458145+davidmcpowell@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:41:09 +0000 Subject: [PATCH] Merge pull request #23384 from overleaf/mj-ide-collapsible-rail [web] Make panels collapsible in editor redesign GitOrigin-RevId: bc979e3b6028666d3e0aa751e341d838615c1aac --- .../web/frontend/extracted-translations.json | 2 + .../components/file-tree-outline-panel.tsx | 11 +++- .../ide-redesign/components/main-layout.tsx | 32 +++++++-- .../features/ide-redesign/components/rail.tsx | 65 ++++++++++++++++--- .../ide-redesign/hooks/use-pdf-pane.tsx | 7 ++ .../features/ide-redesign/hooks/use-rail.tsx | 33 ++++++++++ .../bootstrap-5/pages/editor/rail.scss | 2 +- services/web/locales/en.json | 2 + 8 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 services/web/frontend/js/features/ide-redesign/hooks/use-pdf-pane.tsx create mode 100644 services/web/frontend/js/features/ide-redesign/hooks/use-rail.tsx diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 487c6aed81..e22484be68 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1737,8 +1737,10 @@ "toolbar_undo": "", "toolbar_undo_redo_actions": "", "tooltip_hide_filetree": "", + "tooltip_hide_panel": "", "tooltip_hide_pdf": "", "tooltip_show_filetree": "", + "tooltip_show_panel": "", "tooltip_show_pdf": "", "total_due_today": "", "total_per_month": "", diff --git a/services/web/frontend/js/features/ide-redesign/components/file-tree-outline-panel.tsx b/services/web/frontend/js/features/ide-redesign/components/file-tree-outline-panel.tsx index 4e95b00460..f67619bc3c 100644 --- a/services/web/frontend/js/features/ide-redesign/components/file-tree-outline-panel.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/file-tree-outline-panel.tsx @@ -2,8 +2,11 @@ import { Panel, PanelGroup } from 'react-resizable-panels' import { FileTree } from '@/features/ide-react/components/file-tree' import { OutlineContainer } from '@/features/outline/components/outline-container' import { VerticalResizeHandle } from '@/features/ide-react/components/resize/vertical-resize-handle' +import { useOutlinePane } from '@/features/ide-react/hooks/use-outline-pane' function FileTreeOutlinePanel() { + const { outlineEnabled, outlinePanelRef } = useOutlinePane() + return ( - + diff --git a/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx b/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx index 229f570ca1..71bbbe33c3 100644 --- a/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx @@ -5,8 +5,20 @@ import PdfPreview from '@/features/pdf-preview/components/pdf-preview' import { Editor } from './editor' import { RailLayout } from './rail' import { Toolbar } from './toolbar/toolbar' +import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler' +import { useTranslation } from 'react-i18next' +import { usePdfPane } from '../hooks/use-pdf-pane' export default function MainLayout() { + const { + isOpen: isPdfOpen, + setIsOpen: setIsPdfOpen, + panelRef: pdfPanelRef, + handlePaneCollapse: handlePdfPaneCollapse, + handlePaneExpand: handlePdfPaneExpand, + togglePane: togglePdfPane, + } = usePdfPane() + const { t } = useTranslation() return (
@@ -19,10 +31,6 @@ export default function MainLayout() { })} > -
@@ -30,12 +38,26 @@ export default function MainLayout() { + > + + diff --git a/services/web/frontend/js/features/ide-redesign/components/rail.tsx b/services/web/frontend/js/features/ide-redesign/components/rail.tsx index 3fb89a4a1d..fe3114e375 100644 --- a/services/web/frontend/js/features/ide-redesign/components/rail.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/rail.tsx @@ -10,6 +10,11 @@ import { RailTabKey, useRailTabContext } from '../contexts/rail-tab-context' import FileTreeOutlinePanel from './file-tree-outline-panel' import { ChatIndicator, ChatPane } from './chat' import getMeta from '@/utils/meta' +import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/horizontal-resize-handle' +import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler' +import { useRail } from '../hooks/use-rail' +import { useTranslation } from 'react-i18next' +import classNames from 'classnames' type RailElement = { icon: AvailableUnfilledIcon @@ -59,6 +64,15 @@ const RAIL_TABS: RailElement[] = [ ] export const RailLayout = () => { + const { t } = useTranslation() + const { + isOpen, + setIsOpen, + panelRef, + handlePaneCollapse, + handlePaneExpand, + togglePane, + } = useRail() const { selectedTab, setSelectedTab } = useRailTabContext() const { setLeftMenuShown } = useLayoutContext() @@ -74,16 +88,26 @@ export const RailLayout = () => { [setLeftMenuShown] ) + const onTabSelect = useCallback( + (key: string | null) => { + if (key === selectedTab) { + togglePane() + } else { + // Change the selected tab and make sure it's open + setSelectedTab((key ?? 'file-tree') as RailTabKey) + setIsOpen(true) + } + }, + [setSelectedTab, selectedTab, setIsOpen, togglePane] + ) + return ( setSelectedTab(key ?? undefined), - [setSelectedTab] - )} + onSelect={onTabSelect} id="ide-rail-tabs" >
@@ -94,7 +118,7 @@ export const RailLayout = () => { {RAIL_TABS.filter(({ hide }) => !hide).map( ({ icon, key, indicator }) => ( { defaultSize={15} minSize={5} maxSize={80} + ref={panelRef} + collapsible + onCollapse={handlePaneCollapse} + onExpand={handlePaneExpand} >
@@ -125,6 +153,20 @@ export const RailLayout = () => {
+ + + ) } @@ -132,17 +174,22 @@ export const RailLayout = () => { const RailTab = ({ icon, eventKey, - active, + open, indicator, }: { icon: AvailableUnfilledIcon eventKey: string - active: boolean + open: boolean indicator?: ReactElement }) => { return ( - - {active ? ( + + {open ? ( ) : ( diff --git a/services/web/frontend/js/features/ide-redesign/hooks/use-pdf-pane.tsx b/services/web/frontend/js/features/ide-redesign/hooks/use-pdf-pane.tsx new file mode 100644 index 0000000000..ecab1ac294 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/hooks/use-pdf-pane.tsx @@ -0,0 +1,7 @@ +import { useRail } from './use-rail' + +export const usePdfPane = () => { + // FIXME: This is temporary, to avoid clashing with the existing usePdfPane + // which uses the layout context. That's the correct approach. + return useRail() +} diff --git a/services/web/frontend/js/features/ide-redesign/hooks/use-rail.tsx b/services/web/frontend/js/features/ide-redesign/hooks/use-rail.tsx new file mode 100644 index 0000000000..771a20d672 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/hooks/use-rail.tsx @@ -0,0 +1,33 @@ +import { useCallback, useRef, useState } from 'react' +import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel' +import { ImperativePanelHandle } from 'react-resizable-panels' + +export const useRail = () => { + const [isOpen, setIsOpen] = useState(true) + const [resizing, setResizing] = useState(false) + const panelRef = useRef(null) + useCollapsiblePanel(isOpen, panelRef) + + const togglePane = useCallback(() => { + setIsOpen(value => !value) + }, []) + + const handlePaneExpand = useCallback(() => { + setIsOpen(true) + }, []) + + const handlePaneCollapse = useCallback(() => { + setIsOpen(false) + }, []) + + return { + isOpen, + setIsOpen, + panelRef, + togglePane, + handlePaneExpand, + handlePaneCollapse, + resizing, + setResizing, + } +} diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss index 32e9c9ea32..9af003bfad 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss @@ -28,7 +28,7 @@ font-size: 20px; } - &.active { + &.open-rail { color: var(--ide-rail-color); background-color: var(--ide-rail-link-active-background); diff --git a/services/web/locales/en.json b/services/web/locales/en.json index cfef6b1f2d..9fc78cdb23 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -2265,8 +2265,10 @@ "toolbar_undo": "Undo", "toolbar_undo_redo_actions": "Undo/Redo actions", "tooltip_hide_filetree": "Click to hide the file tree", + "tooltip_hide_panel": "Click to hide the panel", "tooltip_hide_pdf": "Click to hide the PDF", "tooltip_show_filetree": "Click to show the file tree", + "tooltip_show_panel": "Click to show the panel", "tooltip_show_pdf": "Click to show the PDF", "top_pick": "Top pick", "total": "Total",