mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
* feat(app): open files and subagents in a closable sheet on compact On phones, opening a file, a provider subagent, or a Paseo subagent now shows it in a bottom sheet over the current tab instead of adding a tab, so the tab strip stays for terminals and root agents. Paseo subagents get "Open as tab" to move the same tab (same tabId and state) into a full tab with a composer; agents in a sheet hide the composer. The decision lives in the workspace layout store's openTab, driven by a per-kind `compactSheet` rule in the panel manifest, so every open path (chat links, Explorer, subagents track, notifications, plugins) follows it without call-site branching, and a new kind opts in with one manifest entry. The app shell publishes the layout mode (compact / single-pane / split-panes) once, so callers stop passing isCompact for placement. A sheet holding unsaved edits is never implicitly displaced; later opens go to tabs underneath, and closing it goes through the existing discard guard. The editor host is position: sticky because CodeMirror's scrollIntoView otherwise scrolls the bottom sheet's container and drags the sheet to full height. * test(app): fail the compact sheet snap check when the sheet is oversized --------- Co-authored-by: paseo-bot[bot] <paseo-bot[bot]@users.noreply.github.com>
22 lines
962 B
TypeScript
22 lines
962 B
TypeScript
import { useLayoutEffect } from "react";
|
|
import { supportsDesktopPaneSplits, useIsCompactFormFactor } from "@/constants/layout";
|
|
import { useWorkspaceLayoutStore, type WorkspaceLayoutMode } from "@/stores/workspace-layout-store";
|
|
|
|
function resolveWorkspaceLayoutMode(isCompact: boolean): WorkspaceLayoutMode {
|
|
if (isCompact) return "compact";
|
|
return supportsDesktopPaneSplits() ? "split-panes" : "single-pane";
|
|
}
|
|
|
|
/**
|
|
* Publishes the shell's workspace layout to the layout store, which decides where opened targets
|
|
* land. Render it before the routes: React runs an earlier sibling's layout effects before a later
|
|
* sibling's subtree, so a route sees the mode even from its first layout effect.
|
|
*/
|
|
export function WorkspaceLayoutModePublisher(): null {
|
|
const isCompact = useIsCompactFormFactor();
|
|
useLayoutEffect(() => {
|
|
useWorkspaceLayoutStore.getState().setLayoutMode(resolveWorkspaceLayoutMode(isCompact));
|
|
}, [isCompact]);
|
|
return null;
|
|
}
|