From 0d1c8db87d80a0d9147e2af3af5c9a93fded799a Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 29 Jun 2026 12:16:20 +0200 Subject: [PATCH] fix(settings): align host switcher with sidebar rows The host picker reused the composer trigger's content-width pill, so its label sat 6px left of the section rows and the chevron hugged the label instead of the trailing edge. Add a `block` mode to ComboboxTrigger that fills the width and uses the sidebar-row gap, and size the status dot to the icon footprint so the label and chevron line up with the rows below. --- .../app/src/components/ui/combobox-trigger.tsx | 17 ++++++++++++++--- packages/app/src/screens/settings-screen.tsx | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/app/src/components/ui/combobox-trigger.tsx b/packages/app/src/components/ui/combobox-trigger.tsx index de26bf0c9..0fbbb6714 100644 --- a/packages/app/src/components/ui/combobox-trigger.tsx +++ b/packages/app/src/components/ui/combobox-trigger.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useCallback, type ReactElement, type ReactNode } from "react"; +import { forwardRef, useCallback, useMemo, type ReactElement, type ReactNode } from "react"; import { Pressable, View, @@ -28,10 +28,15 @@ interface ComboboxTriggerProps extends Omit(function ComboboxTrigger( - { children, chevron, style, ...props }, + { children, chevron, style, block = false, ...props }, ref, ): ReactElement { const pressableStyle = useCallback( @@ -44,9 +49,11 @@ export const ComboboxTrigger = forwardRef(function C [style], ); + const rowStyle = useMemo(() => [styles.row, block && styles.rowBlock], [block]); + return ( - + {children} {chevron !== null && (chevron ?? ( @@ -68,6 +75,10 @@ const styles = StyleSheet.create((theme) => ({ alignItems: "center", gap: theme.spacing[1], }, + rowBlock: { + flexGrow: 1, + gap: theme.spacing[2], + }, chevronContainer: { flexShrink: 0, transform: [{ translateY: 1 }], diff --git a/packages/app/src/screens/settings-screen.tsx b/packages/app/src/screens/settings-screen.tsx index 2e98bf637..ff262c158 100644 --- a/packages/app/src/screens/settings-screen.tsx +++ b/packages/app/src/screens/settings-screen.tsx @@ -39,7 +39,8 @@ import { AppDiagnosticSheet } from "@/components/app-diagnostic-sheet"; import { ComboboxTrigger } from "@/components/ui/combobox-trigger"; import { SidebarHeaderRow } from "@/components/sidebar/sidebar-header-row"; import { SidebarSeparator } from "@/components/sidebar/sidebar-separator"; -import { HostPicker as SharedHostPicker, HostStatusDotSlot } from "@/components/hosts/host-picker"; +import { HostPicker as SharedHostPicker } from "@/components/hosts/host-picker"; +import { HostStatusDot } from "@/components/host-status-dot"; import { ScreenTitle } from "@/components/headers/screen-title"; import { HeaderIconBadge } from "@/components/headers/header-icon-badge"; import { SettingsSection } from "@/screens/settings/settings-section"; @@ -938,13 +939,18 @@ function HostPicker({ activeServerId, sortedHosts, onSelectHost, onAddHost }: Ho > - {activeHost ? : null} + {activeHost ? ( + + + + ) : null} {activeHost?.label ?? t("settings.groups.host")} @@ -1708,4 +1714,11 @@ const sidebarStyles = StyleSheet.create((theme) => ({ color: theme.colors.foreground, fontWeight: theme.fontWeight.normal, }, + // Match the setting items' icon footprint so the host label aligns with them. + pickerTriggerDot: { + width: theme.iconSize.md, + height: theme.iconSize.md, + alignItems: "center", + justifyContent: "center", + }, }));