diff --git a/frontend/editor/src/core/components/layout/Workbench.tsx b/frontend/editor/src/core/components/layout/Workbench.tsx index 7dbc6f75be..8bc0794140 100644 --- a/frontend/editor/src/core/components/layout/Workbench.tsx +++ b/frontend/editor/src/core/components/layout/Workbench.tsx @@ -18,6 +18,7 @@ import { useCookieConsent } from "@app/hooks/useCookieConsent"; import styles from "@app/components/layout/Workbench.module.css"; import WorkbenchBar from "@app/components/shared/WorkbenchBar"; +import WorkbenchFloatingSearch from "@app/components/shared/WorkbenchFloatingSearch"; import LandingPage from "@app/components/shared/LandingPage"; import DismissAllErrorsButton from "@app/components/shared/DismissAllErrorsButton"; import { ChatFAB } from "@app/components/chat/ChatFAB"; @@ -77,6 +78,22 @@ export default function Workbench() { const [viewerToolbarCollapsed, setViewerToolbarCollapsed] = useState(false); const showReopenTab = currentView === "viewer" && viewerToolbarCollapsed; + // The WorkbenchBar carries file-scoped actions, so it only shows once a file + // is open or a custom view supplies content; otherwise the search floats. + const activeCustomView = customWorkbenchViews.find( + (v) => v.workbenchId === currentView, + ); + const topControlsAvailable = + currentView !== "myFiles" && !activeCustomView?.hideTopControls; + const hasWorkbenchContent = + hasFiles || + fileIds.length > 0 || + !isBaseWorkbench(currentView) || + // Shared signing drives the viewer from the sidebar with no file in context. + (currentView === "viewer" && !!signingOverlay?.file); + const showWorkbenchBar = topControlsAvailable && hasWorkbenchContent; + const showFloatingSearch = topControlsAvailable && !hasWorkbenchContent; + const handlePreviewClose = () => { setPreviewFile(null); const previousMode = sessionStorage.getItem("previousMode"); @@ -231,41 +248,35 @@ export default function Workbench() { data-tour="workbench" style={{ backgroundColor: "var(--c-bg)", minWidth: 0 }} > - {/* Workbench Bar — always visible outside My Files (it hosts the - global search), even with no files loaded. */} - {currentView !== "myFiles" && - !customWorkbenchViews.find((v) => v.workbenchId === currentView) - ?.hideTopControls && ( -
-
-
- -
-
- {/* Reopen tab: a little handle hanging off the bar's bottom-right - while the viewer tool row is retracted. */} - {showReopenTab && ( -
+ )} + {showFloatingSearch && } {/* Dismiss All Errors Button */} diff --git a/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.css b/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.css new file mode 100644 index 0000000000..47c7e9eed4 --- /dev/null +++ b/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.css @@ -0,0 +1,31 @@ +/* Unpainted floating search for the empty workbench. Height + top margin match + the WorkbenchBar's band so opening a file swaps it in without a shift. */ +.workbench-floating-search { + display: flex; + align-items: center; + justify-content: center; + min-height: 38px; + margin-top: var(--nav-gutter); + padding: 0 1rem; + flex-shrink: 0; +} + +.workbench-floating-search .super-search { + flex: 0 1 24rem; + width: min(100%, 24rem); + max-width: 24rem; +} + +.workbench-floating-search .super-search input { + background-color: transparent; + padding-top: 4px; + padding-bottom: 4px; + font-size: 12.5px; +} + +[data-mantine-color-scheme="dark"] + .workbench-floating-search + .super-search + input { + background-color: transparent; +} diff --git a/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.tsx b/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.tsx new file mode 100644 index 0000000000..37e858adff --- /dev/null +++ b/frontend/editor/src/core/components/shared/WorkbenchFloatingSearch.tsx @@ -0,0 +1,15 @@ +import SuperSearch from "@app/components/shared/superSearch/SuperSearch"; +import { useEditorSearchScopes } from "@app/hooks/useSuperSearch"; +import "@app/components/shared/WorkbenchFloatingSearch.css"; + +// The editor's global search, floated while no file is open (mirrors the +// processor's PortalSearchBar). Renders only when the WorkbenchBar doesn't, so +// reusing the default input id is safe. +export default function WorkbenchFloatingSearch() { + const scopes = useEditorSearchScopes(); + return ( +
+ +
+ ); +} diff --git a/frontend/editor/src/portal/components/PortalSearchBar.css b/frontend/editor/src/portal/components/PortalSearchBar.css index cf1d9971c7..8e253b6136 100644 --- a/frontend/editor/src/portal/components/PortalSearchBar.css +++ b/frontend/editor/src/portal/components/PortalSearchBar.css @@ -1,10 +1,11 @@ -/* Slim strip at the top of the main column hosting the shared search bar. - Deliberately unpainted: only the input itself shows, on the page ground. */ +/* Unpainted strip at the top of the main column. Height matches the sidebar's + logo row (.portal-sidebar__logo, 51px) so the search lines up with the brand. */ .portal-searchbar { display: flex; align-items: center; justify-content: center; - padding: 0.22rem 1rem; + min-height: 3.1875rem; + padding: 0 1rem; flex-shrink: 0; }