diff --git a/packages/app/e2e/support/helpers/heartbeats.ts b/packages/app/e2e/support/helpers/heartbeats.ts index ae6552d666..3f074473c2 100644 --- a/packages/app/e2e/support/helpers/heartbeats.ts +++ b/packages/app/e2e/support/helpers/heartbeats.ts @@ -166,6 +166,7 @@ export async function removeSeededSubagent(scenario: AgentHeartbeatScenario): Pr export async function deleteHeartbeat(page: Page, heartbeat: SeededHeartbeat): Promise { const row = page.getByRole("link", { name: `${heartbeat.name}, ${heartbeat.cadence}` }); + await row.hover(); page.once("dialog", (dialog) => void dialog.accept()); await page.getByRole("button", { name: `Delete heartbeat ${heartbeat.name}` }).click(); await expect(row).toHaveCount(0, { timeout: 30_000 }); diff --git a/packages/app/src/composer/tracks.tsx b/packages/app/src/composer/tracks.tsx index 587338270b..7e196923e9 100644 --- a/packages/app/src/composer/tracks.tsx +++ b/packages/app/src/composer/tracks.tsx @@ -17,7 +17,8 @@ import { import { ChevronDown, ChevronRight } from "lucide-react-native"; import { StyleSheet, withUnistyles } from "react-native-unistyles"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; -import { MAX_CONTENT_WIDTH } from "@/constants/layout"; +import { MAX_CONTENT_WIDTH, useIsCompactFormFactor } from "@/constants/layout"; +import { isNative } from "@/constants/platform"; import type { Theme } from "@/styles/theme"; const ThemedChevronDown = withUnistyles(ChevronDown); @@ -166,39 +167,46 @@ export function ComposerTrackRow({ secondary, actions, }: ComposerTrackRowProps): ReactElement { + const isCompact = useIsCompactFormFactor(); const [hovered, setHovered] = useState(false); const [pressed, setPressed] = useState(false); - const handleHoverIn = useCallback(() => setHovered(true), []); - const handleHoverOut = useCallback(() => setHovered(false), []); + const handlePointerEnter = useCallback(() => setHovered(true), []); + const handlePointerLeave = useCallback(() => setHovered(false), []); const handlePressIn = useCallback(() => setPressed(true), []); const handlePressOut = useCallback(() => setPressed(false), []); + const showActions = hovered || isNative || isCompact; return ( - - {() => ( - - - {renderLeading?.()} - - {label} + + + + {renderLeading?.()} + + {label} + + {secondary ? ( + + {secondary} - {secondary ? ( - - {secondary} - - ) : null} - - {actions ? {actions()} : null} - - )} - + ) : null} + + {actions ? ( + + {actions()} + + ) : null} + + ); } @@ -350,10 +358,17 @@ const styles = StyleSheet.create((theme) => ({ fontSize: theme.fontSize.xs, color: theme.colors.foregroundMuted, }, - actionCluster: { + actionClusterVisible: { flexDirection: "row", alignItems: "center", gap: theme.spacing[1], + opacity: 1, + }, + actionClusterHidden: { + flexDirection: "row", + alignItems: "center", + gap: theme.spacing[1], + opacity: 0, }, actionButton: { padding: theme.spacing[1],