From f469223b7647ca632bef40d07a8ab3da473c7b3f Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 17 Aug 2026 23:13:48 +0200 Subject: [PATCH] fix(app): tune composer pill clearance by layout Keep the roomier 16px separation on compact layouts while using 10px on wide layouts. Apply the same breakpoint contract to track and import-session pills so their spacing stays consistent. --- packages/app/src/composer/draft/workspace-tab.tsx | 10 ++++++++-- packages/app/src/composer/pill-styles.ts | 9 ++++++++- packages/app/src/composer/tracks.test.tsx | 10 ++++++++-- packages/app/src/composer/tracks.tsx | 5 ++++- packages/app/src/panels/agent-panel.tsx | 8 +++++--- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/app/src/composer/draft/workspace-tab.tsx b/packages/app/src/composer/draft/workspace-tab.tsx index 9f0f48435..332f8c3fb 100644 --- a/packages/app/src/composer/draft/workspace-tab.tsx +++ b/packages/app/src/composer/draft/workspace-tab.tsx @@ -752,8 +752,14 @@ const styles = StyleSheet.create((theme) => ({ importPillRow: { width: "100%", paddingHorizontal: theme.spacing[4], - paddingTop: COMPOSER_PILL_CLEARANCE, - paddingBottom: COMPOSER_PILL_CLEARANCE, + paddingTop: { + xs: COMPOSER_PILL_CLEARANCE.compact, + md: COMPOSER_PILL_CLEARANCE.wide, + }, + paddingBottom: { + xs: COMPOSER_PILL_CLEARANCE.compact, + md: COMPOSER_PILL_CLEARANCE.wide, + }, alignItems: "center", }, importPillContent: { diff --git a/packages/app/src/composer/pill-styles.ts b/packages/app/src/composer/pill-styles.ts index d85a9df82..6d1dd7d26 100644 --- a/packages/app/src/composer/pill-styles.ts +++ b/packages/app/src/composer/pill-styles.ts @@ -1,9 +1,16 @@ import { StyleSheet } from "react-native-unistyles"; import { SPACING } from "@/styles/theme"; -export const COMPOSER_PILL_CLEARANCE = SPACING[4]; +export const COMPOSER_PILL_CLEARANCE = { + compact: SPACING[4], + wide: 10, +} as const; export const COMPOSER_PILL_MIN_HEIGHT = 32; +export function resolveComposerPillClearance(isCompact: boolean): number { + return isCompact ? COMPOSER_PILL_CLEARANCE.compact : COMPOSER_PILL_CLEARANCE.wide; +} + /** Shared visual contract for the compact pills immediately above the composer. */ export const composerPillStyles = StyleSheet.create((theme) => ({ body: { diff --git a/packages/app/src/composer/tracks.test.tsx b/packages/app/src/composer/tracks.test.tsx index d155cf4c6..60aed29ae 100644 --- a/packages/app/src/composer/tracks.test.tsx +++ b/packages/app/src/composer/tracks.test.tsx @@ -49,7 +49,11 @@ vi.mock("@/components/ui/menu", () => ({ })); import { ComposerTrackBar } from "./tracks"; -import { COMPOSER_PILL_CLEARANCE, composerPillStyles } from "./pill-styles"; +import { + COMPOSER_PILL_CLEARANCE, + composerPillStyles, + resolveComposerPillClearance, +} from "./pill-styles"; describe("ComposerTrackBar", () => { let root: Root | null = null; @@ -96,6 +100,8 @@ describe("ComposerTrackBar", () => { borderRadius: 16, }); expect(composerPillStyles.label).toMatchObject({ fontSize: 12 }); - expect(COMPOSER_PILL_CLEARANCE).toBe(16); + expect(resolveComposerPillClearance(true)).toBe(16); + expect(resolveComposerPillClearance(false)).toBe(10); + expect(COMPOSER_PILL_CLEARANCE).toEqual({ compact: 16, wide: 10 }); }); }); diff --git a/packages/app/src/composer/tracks.tsx b/packages/app/src/composer/tracks.tsx index cd75c3166..8bbc75d1a 100644 --- a/packages/app/src/composer/tracks.tsx +++ b/packages/app/src/composer/tracks.tsx @@ -256,7 +256,10 @@ const styles = StyleSheet.create((theme) => ({ gap: theme.spacing[1], }, pillSpacing: { - marginBottom: COMPOSER_PILL_CLEARANCE, + marginBottom: { + xs: COMPOSER_PILL_CLEARANCE.compact, + md: COMPOSER_PILL_CLEARANCE.wide, + }, }, // The rail every panel row sits on: inset from the panel edge so the fill is a rounded block // inside it, and tall enough that revealing an action button cannot resize the row. diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index 0d3c80d10..7b2175c80 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -25,7 +25,7 @@ import { FileDropZone } from "@/components/file-drop/file-drop-zone"; import { useRetainedPanelActive } from "@/components/retained-panel"; import { SidebarCallout } from "@/components/sidebar-callout"; import { Composer } from "@/composer"; -import { COMPOSER_PILL_CLEARANCE, COMPOSER_PILL_MIN_HEIGHT } from "@/composer/pill-styles"; +import { COMPOSER_PILL_MIN_HEIGHT, resolveComposerPillClearance } from "@/composer/pill-styles"; import { getActiveMessageSubmissions } from "@/composer/submission/model"; import { RewindComposerRestoreProvider } from "@/components/rewind/composer-restore"; import { getProviderIcon } from "@/components/provider-icons"; @@ -1212,6 +1212,8 @@ const ChatAgentReadyContent = memo(function ChatAgentReadyContent({ onOpenWorkspaceFile?: (request: WorkspaceFileOpenRequest) => void; }) { const { t } = useTranslation(); + const isCompactFormFactor = useIsCompactFormFactor(); + const composerPillClearance = resolveComposerPillClearance(isCompactFormFactor); const subagentRows = useSubagentsForParent({ serverId, parentAgentId: agentId }); const tasks = useSessionStore((state): TodoEntry[] | undefined => state.sessions[serverId]?.agentTasks.get(agentId), @@ -1227,7 +1229,7 @@ const ChatAgentReadyContent = memo(function ChatAgentReadyContent({ archiveFinishedStatus: archiveFinishedSubagents.status, }); const [agentTracksHeight, setAgentTracksHeight] = useState( - COMPOSER_PILL_MIN_HEIGHT + COMPOSER_PILL_CLEARANCE, + COMPOSER_PILL_MIN_HEIGHT + composerPillClearance, ); const rawAgentInputDraft = useAgentInputDraft({ draftKey: buildDraftStoreKey({ @@ -1304,7 +1306,7 @@ const ChatAgentReadyContent = memo(function ChatAgentReadyContent({ routeBottomAnchorRequest={routeBottomAnchorRequest} hasAppliedAuthoritativeHistory={hasAppliedAuthoritativeHistory} bottomOverlayHeight={showAgentTracks ? agentTracksHeight : 0} - bottomOverlayClearance={showAgentTracks ? COMPOSER_PILL_CLEARANCE : 0} + bottomOverlayClearance={showAgentTracks ? composerPillClearance : 0} toast={toastApi} onOpenWorkspaceFile={onOpenWorkspaceFile} />