From 5ee4c581870c9a9df7e0ba69eedb9c69162f830f Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Thu, 19 Mar 2026 13:35:55 -0400 Subject: [PATCH 1/5] Add resizable sidebar design spec Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-03-19-resizable-sidebar-design.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md diff --git a/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md b/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md new file mode 100644 index 0000000000..0f977838d5 --- /dev/null +++ b/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md @@ -0,0 +1,49 @@ +# Resizable Sidebar + +## Summary + +Make the sidebar continuously draggable so users can adjust its width. Width persists between sessions. Dragging below a snap threshold collapses the sidebar. No external dependencies — custom drag handler only. + +## Constraints + +- **Min width**: 150px (site names still visible) +- **Max width**: 400px +- **Snap-to-close threshold**: ~100px (below this, sidebar collapses fully) +- **Default width**: 208px (current `SIDEBAR_WIDTH` constant, used as fallback) +- Internal layout rebalances only — no Electron window resizing on drag + +## Resize Handle + +A 4-6px invisible hit area at the sidebar's right edge, between `MainSidebar` and `
` in `app.tsx`. No visible divider — only a `col-resize` cursor on hover/drag signals interactivity. + +## Drag Behavior + +A `useSidebarResize` custom hook manages the interaction: + +- `mousedown` on the handle starts tracking +- `mousemove` on `document` updates sidebar width in real-time via `requestAnimationFrame` +- `mouseup` on `document` ends tracking and persists the final width +- During drag, a transparent overlay covers the content area to prevent iframes from stealing pointer events +- Width is clamped between 150px and 400px +- If dragged below the snap threshold (~100px), the sidebar collapses fully (same as current toggle) +- Reopening a snapped-closed sidebar restores the last dragged width, not the default 208px + +## Persistence + +Width is stored via the existing `user-settings` module. On launch, the app reads the saved width (falling back to 208px). On drag end, the new width is written. Sidebar visibility state (open/collapsed) continues to work independently — persisted width is only applied when the sidebar is visible. + +## Integration with Existing Toggle + +- Toggle button remains unchanged +- Toggling open uses the persisted width instead of hardcoded 208px +- Toggling closed snaps to the collapsed state +- `SIDEBAR_WIDTH` becomes the default/fallback rather than the fixed width +- Auto-collapse breakpoint logic in `use-sidebar-visibility` uses the persisted width for its calculation + +## Files Affected + +- `apps/studio/src/components/app.tsx` — add resize handle element, apply dynamic width +- `apps/studio/src/hooks/use-sidebar-resize.ts` — new hook for drag logic +- `apps/studio/src/hooks/use-sidebar-visibility.ts` — use persisted width instead of constant +- `apps/studio/src/modules/user-settings/` — add sidebar width to persisted settings +- `apps/studio/src/constants.ts` — add min/max/snap-threshold constants From e64c811b8e75a5e710dfe6b60428d60c5c355657 Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Thu, 19 Mar 2026 13:38:03 -0400 Subject: [PATCH 2/5] Update resizable sidebar spec after review Address persistence approach (localStorage vs IPC), toggle window resize math, transition-during-drag conflict, collapsed state drag target, and inline style migration. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-03-19-resizable-sidebar-design.md | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md b/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md index 0f977838d5..cbb0a33944 100644 --- a/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md +++ b/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md @@ -14,7 +14,7 @@ Make the sidebar continuously draggable so users can adjust its width. Width per ## Resize Handle -A 4-6px invisible hit area at the sidebar's right edge, between `MainSidebar` and `
` in `app.tsx`. No visible divider — only a `col-resize` cursor on hover/drag signals interactivity. +A 4-6px invisible hit area at the sidebar's right edge, between `MainSidebar` and `
` in `app.tsx`. No visible divider — only a `col-resize` cursor on hover/drag signals interactivity. In the collapsed state, the existing `!min-w-[10px]` area serves as the grab target so the sidebar can be dragged open again. ## Drag Behavior @@ -26,24 +26,31 @@ A `useSidebarResize` custom hook manages the interaction: - During drag, a transparent overlay covers the content area to prevent iframes from stealing pointer events - Width is clamped between 150px and 400px - If dragged below the snap threshold (~100px), the sidebar collapses fully (same as current toggle) -- Reopening a snapped-closed sidebar restores the last dragged width, not the default 208px +- Reopening a snapped-closed sidebar (via toggle button or dragging from the collapsed edge) restores the last dragged width +- The `transition-all duration-500` class on the sidebar must be removed during active dragging to prevent lag, and re-applied only for toggle animations ## Persistence -Width is stored via the existing `user-settings` module. On launch, the app reads the saved width (falling back to 208px). On drag end, the new width is written. Sidebar visibility state (open/collapsed) continues to work independently — persisted width is only applied when the sidebar is visible. +Width is stored in `localStorage` (similar to `LOCAL_STORAGE_CHAT_MESSAGES_KEY` pattern) rather than appdata via IPC. Sidebar width is renderer-only UI state — no need for file locking or Main process round-trips. On launch, the app reads the saved width (falling back to 208px). On drag end (mouseup only, not every frame), the new width is written. Sidebar visibility state (open/collapsed) continues to work independently — persisted width is only applied when the sidebar is visible. ## Integration with Existing Toggle -- Toggle button remains unchanged +- Toggle button remains unchanged in UI - Toggling open uses the persisted width instead of hardcoded 208px - Toggling closed snaps to the collapsed state - `SIDEBAR_WIDTH` becomes the default/fallback rather than the fixed width -- Auto-collapse breakpoint logic in `use-sidebar-visibility` uses the persisted width for its calculation +- The `toggleMinWindowWidth` IPC handler must use the current sidebar width (passed as an argument) instead of the hardcoded `SIDEBAR_WIDTH` constant, so window resize math is correct +- `MAIN_MIN_WIDTH` calculation becomes dynamic: `currentWindowWidth - currentSidebarWidth + 20` instead of using the constant +- Auto-collapse breakpoint logic in `use-sidebar-visibility` uses the persisted width for its calculation (note: a wider sidebar means auto-collapse triggers sooner during window resize — this is correct behavior) + +## Style Change + +The sidebar currently uses the Tailwind class `basis-52` for its fixed 208px width. This changes to an inline `style={{ flexBasis: width }}` to support dynamic values. The `flex-shrink-0` class remains. ## Files Affected -- `apps/studio/src/components/app.tsx` — add resize handle element, apply dynamic width -- `apps/studio/src/hooks/use-sidebar-resize.ts` — new hook for drag logic +- `apps/studio/src/components/app.tsx` — add resize handle element, apply dynamic width via inline style, conditionally remove transition during drag +- `apps/studio/src/hooks/use-sidebar-resize.ts` — new hook for drag logic and localStorage persistence - `apps/studio/src/hooks/use-sidebar-visibility.ts` — use persisted width instead of constant -- `apps/studio/src/modules/user-settings/` — add sidebar width to persisted settings +- `apps/studio/src/ipc-handlers.ts` — update `toggleMinWindowWidth` to accept current sidebar width - `apps/studio/src/constants.ts` — add min/max/snap-threshold constants From 69449381fd65689860e8684920cfe854bf0d7cb0 Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Thu, 19 Mar 2026 14:05:10 -0400 Subject: [PATCH 3/5] Add resizable sidebar with drag handle and persistence Custom drag-to-resize sidebar with snap-to-close behavior, localStorage persistence, and a blue hover indicator line. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/studio/src/components/app.tsx | 26 ++++- apps/studio/src/components/main-sidebar.tsx | 4 +- apps/studio/src/constants.ts | 4 + apps/studio/src/hooks/use-sidebar-resize.ts | 106 ++++++++++++++++++ .../src/hooks/use-sidebar-visibility.ts | 16 ++- apps/studio/src/ipc-handlers.ts | 9 +- apps/studio/src/preload.ts | 4 +- 7 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 apps/studio/src/hooks/use-sidebar-resize.ts diff --git a/apps/studio/src/components/app.tsx b/apps/studio/src/components/app.tsx index 6683acda5c..2593eb08d3 100644 --- a/apps/studio/src/components/app.tsx +++ b/apps/studio/src/components/app.tsx @@ -12,6 +12,7 @@ import WindowsTitlebar from 'src/components/windows-titlebar'; import { useListenDeepLinkConnection } from 'src/hooks/sync-sites/use-listen-deep-link-connection'; import { useAuth } from 'src/hooks/use-auth'; import { useLocalizationSupport } from 'src/hooks/use-localization-support'; +import { useSidebarResize } from 'src/hooks/use-sidebar-resize'; import { useSidebarVisibility } from 'src/hooks/use-sidebar-visibility'; import { useSiteDetails } from 'src/hooks/use-site-details'; import { isWindows } from 'src/lib/app-globals'; @@ -31,6 +32,10 @@ export default function App() { const { needsOnboarding } = useOnboarding(); const isOnboardingLoading = useRootSelector( selectOnboardingLoading ); const { isSidebarVisible, toggleSidebar } = useSidebarVisibility(); + const { sidebarWidth, isDragging, handleMouseDown } = useSidebarResize( + isSidebarVisible, + toggleSidebar + ); const { showWhatsNew, closeWhatsNew } = useWhatsNew(); const { sites: localSites, loadingSites } = useSiteDetails(); const isEmpty = ! loadingSites && ! localSites.length; @@ -87,10 +92,27 @@ export default function App() { + { /* Resize handle */ } +
+
+
+ { isDragging &&
}
{ ! localSites.length ? (
diff --git a/apps/studio/src/constants.ts b/apps/studio/src/constants.ts index ed48f726ab..5a3452df1a 100644 --- a/apps/studio/src/constants.ts +++ b/apps/studio/src/constants.ts @@ -2,7 +2,11 @@ import { HOUR_MS } from '@studio/common/constants'; export const DEFAULT_WIDTH = 900; export const MAIN_MIN_HEIGHT = 600; export const SIDEBAR_WIDTH = 208; +export const SIDEBAR_MIN_WIDTH = 150; +export const SIDEBAR_MAX_WIDTH = 400; +export const SIDEBAR_SNAP_THRESHOLD = 100; export const MAIN_MIN_WIDTH = DEFAULT_WIDTH - SIDEBAR_WIDTH + 20; +export const LOCAL_STORAGE_SIDEBAR_WIDTH_KEY = 'sidebar_width'; export const APP_CHROME_SPACING = 10; export const MIN_WIDTH_CLASS_TO_MEASURE = 'app-measure-tabs-width'; export const MIN_WIDTH_SELECTOR_TO_MEASURE = `.${ MIN_WIDTH_CLASS_TO_MEASURE }`; diff --git a/apps/studio/src/hooks/use-sidebar-resize.ts b/apps/studio/src/hooks/use-sidebar-resize.ts new file mode 100644 index 0000000000..8dc5d26b41 --- /dev/null +++ b/apps/studio/src/hooks/use-sidebar-resize.ts @@ -0,0 +1,106 @@ +import { useState, useCallback, useRef, useEffect } from 'react'; +import { + SIDEBAR_WIDTH, + SIDEBAR_MIN_WIDTH, + SIDEBAR_MAX_WIDTH, + SIDEBAR_SNAP_THRESHOLD, + LOCAL_STORAGE_SIDEBAR_WIDTH_KEY, +} from 'src/constants'; + +function loadSavedWidth(): number { + const saved = localStorage.getItem( LOCAL_STORAGE_SIDEBAR_WIDTH_KEY ); + if ( saved ) { + const parsed = Number( saved ); + if ( ! isNaN( parsed ) && parsed >= SIDEBAR_MIN_WIDTH && parsed <= SIDEBAR_MAX_WIDTH ) { + return parsed; + } + } + return SIDEBAR_WIDTH; +} + +function saveWidth( width: number ) { + localStorage.setItem( LOCAL_STORAGE_SIDEBAR_WIDTH_KEY, String( width ) ); +} + +export function useSidebarResize( isSidebarVisible: boolean, toggleSidebar: () => void ) { + const [ sidebarWidth, setSidebarWidth ] = useState( loadSavedWidth ); + const [ isDragging, setIsDragging ] = useState( false ); + const dragStartX = useRef( 0 ); + const dragStartWidth = useRef( 0 ); + + const handleMouseDown = useCallback( + ( e: React.MouseEvent ) => { + e.preventDefault(); + setIsDragging( true ); + dragStartX.current = e.clientX; + dragStartWidth.current = isSidebarVisible ? sidebarWidth : 0; + }, + [ sidebarWidth, isSidebarVisible ] + ); + + useEffect( () => { + if ( ! isDragging ) { + return; + } + + let rafId: number; + + const handleMouseMove = ( e: MouseEvent ) => { + cancelAnimationFrame( rafId ); + rafId = requestAnimationFrame( () => { + const delta = e.clientX - dragStartX.current; + const newWidth = dragStartWidth.current + delta; + + if ( newWidth < SIDEBAR_SNAP_THRESHOLD ) { + // Will snap closed on mouseup + setSidebarWidth( Math.max( 0, newWidth ) ); + return; + } + + setSidebarWidth( Math.min( SIDEBAR_MAX_WIDTH, Math.max( SIDEBAR_MIN_WIDTH, newWidth ) ) ); + } ); + }; + + const handleMouseUp = ( e: MouseEvent ) => { + setIsDragging( false ); + cancelAnimationFrame( rafId ); + + const delta = e.clientX - dragStartX.current; + const finalWidth = dragStartWidth.current + delta; + + if ( finalWidth < SIDEBAR_SNAP_THRESHOLD ) { + // Snap closed — restore the last good width for when it reopens + setSidebarWidth( + dragStartWidth.current > SIDEBAR_MIN_WIDTH ? dragStartWidth.current : SIDEBAR_WIDTH + ); + if ( isSidebarVisible ) { + toggleSidebar(); + } + return; + } + + const clampedWidth = Math.min( SIDEBAR_MAX_WIDTH, Math.max( SIDEBAR_MIN_WIDTH, finalWidth ) ); + setSidebarWidth( clampedWidth ); + saveWidth( clampedWidth ); + + if ( ! isSidebarVisible ) { + toggleSidebar(); + } + }; + + document.addEventListener( 'mousemove', handleMouseMove ); + document.addEventListener( 'mouseup', handleMouseUp ); + + return () => { + cancelAnimationFrame( rafId ); + document.removeEventListener( 'mousemove', handleMouseMove ); + document.removeEventListener( 'mouseup', handleMouseUp ); + }; + }, [ isDragging, isSidebarVisible, toggleSidebar ] ); + + return { + sidebarWidth, + isDragging, + handleMouseDown, + }; +} diff --git a/apps/studio/src/hooks/use-sidebar-visibility.ts b/apps/studio/src/hooks/use-sidebar-visibility.ts index 6352c2e6b2..693d19df59 100644 --- a/apps/studio/src/hooks/use-sidebar-visibility.ts +++ b/apps/studio/src/hooks/use-sidebar-visibility.ts @@ -4,9 +4,21 @@ import { SIDEBAR_WIDTH, MIN_WIDTH_SELECTOR_TO_MEASURE, APP_CHROME_SPACING, + LOCAL_STORAGE_SIDEBAR_WIDTH_KEY, } from 'src/constants'; import { getIpcApi } from 'src/lib/get-ipc-api'; +function getCurrentSidebarWidth(): number { + const saved = localStorage.getItem( LOCAL_STORAGE_SIDEBAR_WIDTH_KEY ); + if ( saved ) { + const parsed = Number( saved ); + if ( ! isNaN( parsed ) && parsed > 0 ) { + return parsed; + } + } + return SIDEBAR_WIDTH; +} + const SIDEBAR_BREAKPOINT = DEFAULT_WIDTH; /** @@ -35,7 +47,7 @@ export function useSidebarVisibility( elementSelector: string = MIN_WIDTH_SELECT el?.clientWidth < el?.scrollWidth ) { // The new breakpoint is the width of the element to measure plus the sidebar plus the right padding - setDynamicBreakPoint( el.clientWidth + SIDEBAR_WIDTH + APP_CHROME_SPACING ); + setDynamicBreakPoint( el.clientWidth + getCurrentSidebarWidth() + APP_CHROME_SPACING ); } setIsLowerThanBreakpoint( window.innerWidth < dynamicBreakPoint ); @@ -55,7 +67,7 @@ export function useSidebarVisibility( elementSelector: string = MIN_WIDTH_SELECT }, [ isLowerThanBreakpoint ] ); const toggleSidebar = useCallback( () => { - void getIpcApi().toggleMinWindowWidth( isSidebarVisible ); + void getIpcApi().toggleMinWindowWidth( isSidebarVisible, getCurrentSidebarWidth() ); setIsSidebarVisible( ! isSidebarVisible ); }, [ isSidebarVisible ] ); diff --git a/apps/studio/src/ipc-handlers.ts b/apps/studio/src/ipc-handlers.ts index 0035f8261e..48ca950090 100644 --- a/apps/studio/src/ipc-handlers.ts +++ b/apps/studio/src/ipc-handlers.ts @@ -1223,15 +1223,20 @@ export function resetDefaultLocaleData( _event: IpcMainInvokeEvent ) { defaultI18n.resetLocaleData(); } -export function toggleMinWindowWidth( event: IpcMainInvokeEvent, isSidebarVisible: boolean ) { +export function toggleMinWindowWidth( + event: IpcMainInvokeEvent, + isSidebarVisible: boolean, + currentSidebarWidth?: number +) { const parentWindow = BrowserWindow.fromWebContents( event.sender ); if ( ! parentWindow || parentWindow.isDestroyed() || event.sender.isDestroyed() ) { return; } + const sidebarW = currentSidebarWidth ?? SIDEBAR_WIDTH; const [ currentWidth, currentHeight ] = parentWindow.getSize(); const newWidth = Math.max( MAIN_MIN_WIDTH, - isSidebarVisible ? currentWidth - SIDEBAR_WIDTH : currentWidth + SIDEBAR_WIDTH + isSidebarVisible ? currentWidth - sidebarW : currentWidth + sidebarW ); parentWindow.setSize( newWidth, currentHeight, true ); } diff --git a/apps/studio/src/preload.ts b/apps/studio/src/preload.ts index ec7eed15a5..1015341193 100644 --- a/apps/studio/src/preload.ts +++ b/apps/studio/src/preload.ts @@ -113,8 +113,8 @@ const api: IpcApi = { ipcRendererInvoke( 'promptWindowsSpeedUpSites', ...args ), setDefaultLocaleData: ( locale ) => ipcRendererInvoke( 'setDefaultLocaleData', locale ), resetDefaultLocaleData: () => ipcRendererInvoke( 'resetDefaultLocaleData' ), - toggleMinWindowWidth: ( isSidebarVisible ) => - ipcRendererInvoke( 'toggleMinWindowWidth', isSidebarVisible ), + toggleMinWindowWidth: ( isSidebarVisible, currentSidebarWidth? ) => + ipcRendererInvoke( 'toggleMinWindowWidth', isSidebarVisible, currentSidebarWidth ), getAbsolutePathFromSite: ( siteId, relativePath ) => ipcRendererInvoke( 'getAbsolutePathFromSite', siteId, relativePath ), openFileInIDE: ( relativePath, siteId ) => From f9f43cbb9247a5757d39764ec965d8805cdd3183 Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Thu, 19 Mar 2026 14:09:44 -0400 Subject: [PATCH 4/5] Remove design spec from PR Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-03-19-resizable-sidebar-design.md | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md diff --git a/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md b/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md deleted file mode 100644 index cbb0a33944..0000000000 --- a/docs/superpowers/specs/2026-03-19-resizable-sidebar-design.md +++ /dev/null @@ -1,56 +0,0 @@ -# Resizable Sidebar - -## Summary - -Make the sidebar continuously draggable so users can adjust its width. Width persists between sessions. Dragging below a snap threshold collapses the sidebar. No external dependencies — custom drag handler only. - -## Constraints - -- **Min width**: 150px (site names still visible) -- **Max width**: 400px -- **Snap-to-close threshold**: ~100px (below this, sidebar collapses fully) -- **Default width**: 208px (current `SIDEBAR_WIDTH` constant, used as fallback) -- Internal layout rebalances only — no Electron window resizing on drag - -## Resize Handle - -A 4-6px invisible hit area at the sidebar's right edge, between `MainSidebar` and `
` in `app.tsx`. No visible divider — only a `col-resize` cursor on hover/drag signals interactivity. In the collapsed state, the existing `!min-w-[10px]` area serves as the grab target so the sidebar can be dragged open again. - -## Drag Behavior - -A `useSidebarResize` custom hook manages the interaction: - -- `mousedown` on the handle starts tracking -- `mousemove` on `document` updates sidebar width in real-time via `requestAnimationFrame` -- `mouseup` on `document` ends tracking and persists the final width -- During drag, a transparent overlay covers the content area to prevent iframes from stealing pointer events -- Width is clamped between 150px and 400px -- If dragged below the snap threshold (~100px), the sidebar collapses fully (same as current toggle) -- Reopening a snapped-closed sidebar (via toggle button or dragging from the collapsed edge) restores the last dragged width -- The `transition-all duration-500` class on the sidebar must be removed during active dragging to prevent lag, and re-applied only for toggle animations - -## Persistence - -Width is stored in `localStorage` (similar to `LOCAL_STORAGE_CHAT_MESSAGES_KEY` pattern) rather than appdata via IPC. Sidebar width is renderer-only UI state — no need for file locking or Main process round-trips. On launch, the app reads the saved width (falling back to 208px). On drag end (mouseup only, not every frame), the new width is written. Sidebar visibility state (open/collapsed) continues to work independently — persisted width is only applied when the sidebar is visible. - -## Integration with Existing Toggle - -- Toggle button remains unchanged in UI -- Toggling open uses the persisted width instead of hardcoded 208px -- Toggling closed snaps to the collapsed state -- `SIDEBAR_WIDTH` becomes the default/fallback rather than the fixed width -- The `toggleMinWindowWidth` IPC handler must use the current sidebar width (passed as an argument) instead of the hardcoded `SIDEBAR_WIDTH` constant, so window resize math is correct -- `MAIN_MIN_WIDTH` calculation becomes dynamic: `currentWindowWidth - currentSidebarWidth + 20` instead of using the constant -- Auto-collapse breakpoint logic in `use-sidebar-visibility` uses the persisted width for its calculation (note: a wider sidebar means auto-collapse triggers sooner during window resize — this is correct behavior) - -## Style Change - -The sidebar currently uses the Tailwind class `basis-52` for its fixed 208px width. This changes to an inline `style={{ flexBasis: width }}` to support dynamic values. The `flex-shrink-0` class remains. - -## Files Affected - -- `apps/studio/src/components/app.tsx` — add resize handle element, apply dynamic width via inline style, conditionally remove transition during drag -- `apps/studio/src/hooks/use-sidebar-resize.ts` — new hook for drag logic and localStorage persistence -- `apps/studio/src/hooks/use-sidebar-visibility.ts` — use persisted width instead of constant -- `apps/studio/src/ipc-handlers.ts` — update `toggleMinWindowWidth` to accept current sidebar width -- `apps/studio/src/constants.ts` — add min/max/snap-threshold constants From da52e8f230c235c9bed5e39bd4149d7470ecbd60 Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Thu, 19 Mar 2026 14:16:53 -0400 Subject: [PATCH 5/5] Increase sidebar min width and prevent footer text wrapping Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/studio/src/components/running-sites.tsx | 2 +- apps/studio/src/constants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/studio/src/components/running-sites.tsx b/apps/studio/src/components/running-sites.tsx index f9ea565425..4ba4d4d1a7 100644 --- a/apps/studio/src/components/running-sites.tsx +++ b/apps/studio/src/components/running-sites.tsx @@ -22,7 +22,7 @@ export function RunningSites() { } return ( -
+

{ anyRunning ? sprintf( diff --git a/apps/studio/src/constants.ts b/apps/studio/src/constants.ts index 5a3452df1a..dc12b99591 100644 --- a/apps/studio/src/constants.ts +++ b/apps/studio/src/constants.ts @@ -2,7 +2,7 @@ import { HOUR_MS } from '@studio/common/constants'; export const DEFAULT_WIDTH = 900; export const MAIN_MIN_HEIGHT = 600; export const SIDEBAR_WIDTH = 208; -export const SIDEBAR_MIN_WIDTH = 150; +export const SIDEBAR_MIN_WIDTH = 200; export const SIDEBAR_MAX_WIDTH = 400; export const SIDEBAR_SNAP_THRESHOLD = 100; export const MAIN_MIN_WIDTH = DEFAULT_WIDTH - SIDEBAR_WIDTH + 20;