Skip to content

Commit 1509e7d

Browse files
committed
fix(modals): center modals in visible content area accounting for sidebar and panel (#3934)
* fix(modals): center modals in visible content area accounting for sidebar and panel * fix(modals): address pr feedback — comment clarity and document panel assumption
1 parent 5be4efe commit 1509e7d

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed

apps/sim/app/_styles/globals.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* @see stores/constants.ts for the source of truth
1111
*/
1212
:root {
13-
--sidebar-width: 248px; /* SIDEBAR_WIDTH.DEFAULT */
13+
--sidebar-width: 0px; /* 0 outside workspace; blocking script always sets actual value on workspace pages */
1414
--panel-width: 320px; /* PANEL_WIDTH.DEFAULT */
1515
--toolbar-triggers-height: 300px; /* TOOLBAR_TRIGGERS_HEIGHT.DEFAULT */
1616
--editor-connections-height: 172px; /* EDITOR_CONNECTIONS_HEIGHT.DEFAULT */

apps/sim/app/layout.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
9090
}
9191
9292
// Sidebar width
93+
var defaultSidebarWidth = '248px';
9394
try {
9495
var stored = localStorage.getItem('sidebar-state');
9596
if (stored) {
@@ -108,11 +109,15 @@ export default function RootLayout({ children }: { children: React.ReactNode })
108109
document.documentElement.style.setProperty('--sidebar-width', width + 'px');
109110
} else if (width > maxSidebarWidth) {
110111
document.documentElement.style.setProperty('--sidebar-width', maxSidebarWidth + 'px');
112+
} else {
113+
document.documentElement.style.setProperty('--sidebar-width', defaultSidebarWidth);
111114
}
112115
}
116+
} else {
117+
document.documentElement.style.setProperty('--sidebar-width', defaultSidebarWidth);
113118
}
114119
} catch (e) {
115-
// Fallback handled by CSS defaults
120+
document.documentElement.style.setProperty('--sidebar-width', defaultSidebarWidth);
116121
}
117122
118123
// Panel width and active tab

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,11 @@ export function SearchModal({
343343
'-translate-x-1/2 fixed top-[15%] z-50 w-[500px] rounded-xl border-[4px] border-black/[0.06] bg-[var(--bg)] shadow-[0_24px_80px_-16px_rgba(0,0,0,0.15)] dark:border-white/[0.06] dark:shadow-[0_24px_80px_-16px_rgba(0,0,0,0.4)]',
344344
open ? 'visible opacity-100' : 'invisible opacity-0'
345345
)}
346-
style={{ left: 'calc(var(--sidebar-width) / 2 + 50%)' }}
346+
style={{
347+
left: isOnWorkflowPage
348+
? 'calc(50% + (var(--sidebar-width) - var(--panel-width)) / 2)'
349+
: 'calc(var(--sidebar-width) / 2 + 50%)',
350+
}}
347351
>
348352
<Command label='Search' shouldFilter={false}>
349353
<div className='mx-2 mt-2 mb-1 flex items-center gap-1.5 rounded-lg border border-[var(--border-1)] bg-[var(--surface-5)] px-2 dark:bg-[var(--surface-4)]'>

apps/sim/components/emcn/components/modal/modal.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import * as React from 'react'
4040
import * as DialogPrimitive from '@radix-ui/react-dialog'
4141
import * as TabsPrimitive from '@radix-ui/react-tabs'
4242
import { X } from 'lucide-react'
43+
import { usePathname } from 'next/navigation'
4344
import { cn } from '@/lib/core/utils/cn'
4445
import { Button } from '../button/button'
4546

@@ -55,7 +56,7 @@ const ANIMATION_CLASSES =
5556
* We keep only the slide animations (no zoom) to stabilize positioning while avoiding scale effects.
5657
*/
5758
const CONTENT_ANIMATION_CLASSES =
58-
'data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[50%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[50%] motion-reduce:animate-none'
59+
'data-[state=closed]:slide-out-to-top-[50%] data-[state=open]:slide-in-from-top-[50%] motion-reduce:animate-none'
5960

6061
/**
6162
* Root modal component. Manages open state.
@@ -145,6 +146,8 @@ const ModalContent = React.forwardRef<
145146
ModalContentProps
146147
>(({ className, children, showClose = true, size = 'md', style, ...props }, ref) => {
147148
const [isInteractionReady, setIsInteractionReady] = React.useState(false)
149+
const pathname = usePathname()
150+
const isWorkflowPage = pathname?.includes('/w/') ?? false
148151

149152
React.useEffect(() => {
150153
const timer = setTimeout(() => setIsInteractionReady(true), 100)
@@ -164,7 +167,10 @@ const ModalContent = React.forwardRef<
164167
className
165168
)}
166169
style={{
167-
left: '50%',
170+
left: isWorkflowPage
171+
? // --panel-width is always the rendered panel width on /w/ routes (panel is never hidden/collapsed)
172+
'calc(50% + (var(--sidebar-width) - var(--panel-width)) / 2)'
173+
: 'calc(var(--sidebar-width) / 2 + 50%)',
168174
...style,
169175
}}
170176
onEscapeKeyDown={(e) => {

0 commit comments

Comments
 (0)