import { useCallback, useMemo, useRef, useState } from "react"; import { View, Text, Platform, Pressable, Keyboard } from "react-native"; import { StyleSheet, useUnistyles } from "react-native-unistyles"; import { useShallow } from "zustand/shallow"; import { useStoreWithEqualityFn } from "zustand/traditional"; import { Brain, ChevronDown, ListTodo, Settings2, ShieldAlert, ShieldCheck, ShieldOff, Zap, } from "lucide-react-native"; import { getProviderIcon } from "@/components/provider-icons"; import { CombinedModelSelector } from "@/components/combined-model-selector"; import { useQuery } from "@tanstack/react-query"; import { useSessionStore } from "@/stores/session-store"; import { buildFavoriteModelKey, mergeProviderPreferences, toggleFavoriteModel, useFormPreferences, } from "@/hooks/use-form-preferences"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Combobox, ComboboxItem, type ComboboxOption } from "@/components/ui/combobox"; import { AdaptiveModalSheet } from "@/components/adaptive-modal-sheet"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import type { AgentFeature, AgentMode, AgentModelDefinition, AgentProvider, } from "@server/server/agent/agent-sdk-types"; import type { AgentProviderDefinition } from "@server/server/agent/provider-manifest"; import { AGENT_PROVIDER_DEFINITIONS, getModeVisuals, type AgentModeColorTier, type AgentModeIcon, } from "@server/server/agent/provider-manifest"; import { getFeatureHighlightColor, getFeatureTooltip, getStatusSelectorHint, resolveAgentModelSelection, } from "@/components/agent-status-bar.utils"; import { isProviderModelsQueryLoading } from "@/components/agent-status-bar.model-loading"; type StatusOption = { id: string; label: string; }; type StatusSelector = "provider" | "mode" | "model" | "thinking" | `feature-${string}`; const PROVIDER_DEFINITION_MAP = new Map( AGENT_PROVIDER_DEFINITIONS.map((definition) => [definition.id, definition]), ); type ControlledAgentStatusBarProps = { provider: string; providerOptions?: StatusOption[]; selectedProviderId?: string; onSelectProvider?: (providerId: string) => void; modeOptions?: StatusOption[]; selectedModeId?: string; onSelectMode?: (modeId: string) => void; modelOptions?: StatusOption[]; selectedModelId?: string; onSelectModel?: (modelId: string) => void; thinkingOptions?: StatusOption[]; selectedThinkingOptionId?: string; onSelectThinkingOption?: (thinkingOptionId: string) => void; disabled?: boolean; isModelLoading?: boolean; providerDefinitions?: AgentProviderDefinition[]; allProviderModels?: Map; canSelectModelProvider?: (providerId: string) => boolean; favoriteKeys?: Set; onToggleFavoriteModel?: (provider: string, modelId: string) => void; features?: AgentFeature[]; onSetFeature?: (featureId: string, value: unknown) => void; onDropdownClose?: () => void; }; export interface DraftAgentStatusBarProps { providerDefinitions: AgentProviderDefinition[]; selectedProvider: AgentProvider; onSelectProvider: (provider: AgentProvider) => void; modeOptions: AgentMode[]; selectedMode: string; onSelectMode: (modeId: string) => void; models: AgentModelDefinition[]; selectedModel: string; onSelectModel: (modelId: string) => void; isModelLoading: boolean; allProviderModels: Map; isAllModelsLoading: boolean; onSelectProviderAndModel: (provider: AgentProvider, modelId: string) => void; thinkingOptions: NonNullable; selectedThinkingOptionId: string; onSelectThinkingOption: (thinkingOptionId: string) => void; features?: AgentFeature[]; onSetFeature?: (featureId: string, value: unknown) => void; onDropdownClose?: () => void; disabled?: boolean; } interface AgentStatusBarProps { agentId: string; serverId: string; onDropdownClose?: () => void; } function findOptionLabel( options: StatusOption[] | undefined, selectedId: string | undefined, fallback: string, ) { if (!options || options.length === 0) { return fallback; } const selected = options.find((option) => option.id === selectedId); return selected?.label ?? fallback; } const FEATURE_ICONS: Record = { "list-todo": ListTodo, zap: Zap, }; function getFeatureIcon(icon?: string) { return (icon && FEATURE_ICONS[icon]) || Settings2; } function getFeatureIconColor( featureId: string, enabled: boolean, palette: { blue: { 400: string }; yellow: { 400: string }; }, foregroundMuted: string, ): string { if (!enabled) { return foregroundMuted; } switch (getFeatureHighlightColor(featureId)) { case "blue": return palette.blue[400]; case "yellow": return palette.yellow[400]; default: return foregroundMuted; } } const MODE_ICONS = { ShieldCheck, ShieldAlert, ShieldOff, } as const; function getModeIconColor( colorTier: AgentModeColorTier | undefined, palette: { blue: { 500: string }; green: { 500: string }; red: { 500: string }; purple: { 500: string }; }, ): string { switch (colorTier) { case "safe": return palette.green[500]; case "moderate": return palette.blue[500]; case "dangerous": return palette.red[500]; case "planning": return palette.purple[500]; default: return palette.blue[500]; } } function ControlledStatusBar({ provider, providerOptions, selectedProviderId, onSelectProvider, modeOptions, selectedModeId, onSelectMode, modelOptions, selectedModelId, onSelectModel, thinkingOptions, selectedThinkingOptionId, onSelectThinkingOption, disabled = false, isModelLoading = false, providerDefinitions, allProviderModels, canSelectModelProvider, favoriteKeys = new Set(), onToggleFavoriteModel, features, onSetFeature, onDropdownClose, }: ControlledAgentStatusBarProps) { const { theme } = useUnistyles(); const isWeb = Platform.OS === "web"; const [prefsOpen, setPrefsOpen] = useState(false); const [openSelector, setOpenSelector] = useState(null); const providerAnchorRef = useRef(null); const modeAnchorRef = useRef(null); const modelAnchorRef = useRef(null); const thinkingAnchorRef = useRef(null); const canSelectProvider = Boolean( onSelectProvider && providerOptions && providerOptions.length > 0, ); const canSelectMode = Boolean(onSelectMode && modeOptions && modeOptions.length > 0); const canSelectModel = Boolean(onSelectModel); const canSelectThinking = Boolean( onSelectThinkingOption && thinkingOptions && thinkingOptions.length > 0, ); const displayProvider = findOptionLabel(providerOptions, selectedProviderId, "Provider"); const displayMode = findOptionLabel(modeOptions, selectedModeId, "Default"); const displayModel = isModelLoading && (!modelOptions || modelOptions.length === 0) ? "Loading models..." : findOptionLabel(modelOptions, selectedModelId, "Select model"); const displayThinking = findOptionLabel( thinkingOptions, selectedThinkingOptionId, thinkingOptions?.[0]?.label ?? "Unknown", ); const modeVisuals = selectedModeId ? getModeVisuals(provider, selectedModeId) : undefined; const ModeIconComponent = modeVisuals?.icon ? MODE_ICONS[modeVisuals.icon] : null; const modeIconColor = getModeIconColor(modeVisuals?.colorTier, theme.colors.palette); const ProviderIcon = getProviderIcon(provider); const hasAnyControl = Boolean(providerOptions?.length) || Boolean(modeOptions?.length) || canSelectModel || Boolean(thinkingOptions?.length) || Boolean(features?.length); if (!hasAnyControl) { return null; } const modelDisabled = disabled || isModelLoading || !modelOptions || modelOptions.length === 0; const SEARCH_THRESHOLD = 6; const comboboxProviderOptions = useMemo( () => (providerOptions ?? []).map((o) => ({ id: o.id, label: o.label })), [providerOptions], ); const comboboxModeOptions = useMemo( () => (modeOptions ?? []).map((o) => ({ id: o.id, label: o.label })), [modeOptions], ); const comboboxModelOptions = useMemo( () => (modelOptions ?? []).map((o) => ({ id: o.id, label: o.label })), [modelOptions], ); const fallbackAllProviderModels = useMemo(() => { const map = new Map(); if (!modelOptions || modelOptions.length === 0) { return map; } map.set( provider, modelOptions.map((option) => ({ provider: provider as AgentProvider, id: option.id, label: option.label, })), ); return map; }, [modelOptions, provider]); const effectiveProviderDefinitions = providerDefinitions ?? (PROVIDER_DEFINITION_MAP.has(provider) ? [PROVIDER_DEFINITION_MAP.get(provider)!] : []); const effectiveAllProviderModels = allProviderModels ?? fallbackAllProviderModels; const canSelectProviderInModelMenu = canSelectModelProvider ?? (() => true); const comboboxThinkingOptions = useMemo( () => (thinkingOptions ?? []).map((o) => ({ id: o.id, label: o.label })), [thinkingOptions], ); const renderModeOption = useCallback( ({ option, selected, active, onPress, }: { option: ComboboxOption; selected: boolean; active: boolean; onPress: () => void; }) => { const visuals = getModeVisuals(provider, option.id); const IconComponent = visuals?.icon ? MODE_ICONS[visuals.icon] : ShieldCheck; return ( } /> ); }, [provider, theme.colors.foreground], ); const handleOpenChange = useCallback( (selector: StatusSelector) => (nextOpen: boolean) => { setOpenSelector(nextOpen ? selector : null); if (!nextOpen) { onDropdownClose?.(); } }, [onDropdownClose], ); const handleSelectorPress = useCallback( (selector: StatusSelector) => { handleOpenChange(selector)(openSelector !== selector); }, [handleOpenChange, openSelector], ); return ( {isWeb ? ( <> {providerOptions && providerOptions.length > 0 ? ( <> handleSelectorPress("provider")} style={({ pressed, hovered }) => [ styles.modeBadge, hovered && styles.modeBadgeHovered, (pressed || openSelector === "provider") && styles.modeBadgePressed, (disabled || !canSelectProvider) && styles.disabledBadge, ]} accessibilityRole="button" accessibilityLabel="Select agent provider" testID="agent-provider-selector" > {displayProvider} onSelectProvider?.(id)} searchable={comboboxProviderOptions.length > SEARCH_THRESHOLD} open={openSelector === "provider"} onOpenChange={handleOpenChange("provider")} anchorRef={providerAnchorRef} desktopPlacement="top-start" /> ) : null} {canSelectModel ? ( { if (selectedProviderId === provider) { onSelectModel?.(modelId); } }} favoriteKeys={favoriteKeys} onToggleFavorite={onToggleFavoriteModel} isLoading={isModelLoading} disabled={modelDisabled} onClose={onDropdownClose} /> {getStatusSelectorHint("model")} ) : null} {thinkingOptions && thinkingOptions.length > 0 ? ( <> handleSelectorPress("thinking")} style={({ pressed, hovered }) => [ styles.modeBadge, hovered && styles.modeBadgeHovered, (pressed || openSelector === "thinking") && styles.modeBadgePressed, (disabled || !canSelectThinking) && styles.disabledBadge, ]} accessibilityRole="button" accessibilityLabel={`Select thinking option (${displayThinking})`} testID="agent-thinking-selector" > {displayThinking} {getStatusSelectorHint("thinking")} onSelectThinkingOption?.(id)} searchable={comboboxThinkingOptions.length > SEARCH_THRESHOLD} open={openSelector === "thinking"} onOpenChange={handleOpenChange("thinking")} anchorRef={thinkingAnchorRef} desktopPlacement="top-start" /> ) : null} {modeOptions && modeOptions.length > 0 ? ( <> handleSelectorPress("mode")} style={({ pressed, hovered }) => [ styles.modeIconBadge, hovered && styles.modeBadgeHovered, (pressed || openSelector === "mode") && styles.modeBadgePressed, (disabled || !canSelectMode) && styles.disabledBadge, ]} accessibilityRole="button" accessibilityLabel={`Select agent mode (${displayMode})`} testID="agent-mode-selector" > {ModeIconComponent ? ( ) : ( )} {getStatusSelectorHint("mode")} onSelectMode?.(id)} searchable={comboboxModeOptions.length > SEARCH_THRESHOLD} open={openSelector === "mode"} onOpenChange={handleOpenChange("mode")} anchorRef={modeAnchorRef} desktopPlacement="top-start" renderOption={renderModeOption} /> ) : null} {features?.map((feature) => { if (feature.type === "toggle") { const FeatureIcon = getFeatureIcon(feature.icon); return ( onSetFeature?.(feature.id, !feature.value)} style={({ pressed, hovered }) => [ styles.modeIconBadge, hovered && styles.modeBadgeHovered, pressed && styles.modeBadgePressed, disabled && styles.disabledBadge, ]} accessibilityRole="button" accessibilityLabel={getFeatureTooltip(feature)} testID={`agent-feature-${feature.id}`} > {getFeatureTooltip(feature)} ); } if (feature.type === "select") { const FeatureIcon = getFeatureIcon(feature.icon); const selectedOption = feature.options.find((o) => o.id === feature.value); return ( [ styles.modeBadge, hovered && styles.modeBadgeHovered, (pressed || openSelector === `feature-${feature.id}`) && styles.modeBadgePressed, disabled && styles.disabledBadge, ]} accessibilityRole="button" accessibilityLabel={getFeatureTooltip(feature)} testID={`agent-feature-${feature.id}`} > {selectedOption?.label ?? feature.label} {getFeatureTooltip(feature)} {feature.options.map((option) => ( onSetFeature?.(feature.id, option.id)} > {option.label} ))} ); } return null; })} ) : ( <> { Keyboard.dismiss(); setPrefsOpen(true); }} style={({ pressed }) => [styles.prefsButton, pressed && styles.prefsButtonPressed]} accessibilityRole="button" accessibilityLabel="Agent preferences" testID="agent-preferences-button" > {displayModel} setPrefsOpen(false)} stackBehavior="replace" testID="agent-preferences-sheet" > {canSelectModel ? ( { if (selectedProviderId !== provider) { onSelectProvider?.(selectedProviderId); } onSelectModel?.(modelId); }} favoriteKeys={favoriteKeys} onToggleFavorite={onToggleFavoriteModel} isLoading={isModelLoading} disabled={modelDisabled} onClose={onDropdownClose} renderTrigger={({ selectedModelLabel }) => ( {selectedModelLabel} )} /> ) : null} {thinkingOptions && thinkingOptions.length > 0 ? ( [ styles.sheetSelect, pressed && styles.sheetSelectPressed, (disabled || !canSelectThinking) && styles.disabledSheetSelect, ]} accessibilityRole="button" accessibilityLabel="Select thinking option" testID="agent-preferences-thinking" > {displayThinking} {thinkingOptions.map((thinking) => ( onSelectThinkingOption?.(thinking.id)} > {thinking.label} ))} ) : null} {modeOptions && modeOptions.length > 0 ? ( [ styles.sheetSelect, pressed && styles.sheetSelectPressed, (disabled || !canSelectMode) && styles.disabledSheetSelect, ]} accessibilityRole="button" accessibilityLabel="Select agent mode" testID="agent-preferences-mode" > {ModeIconComponent ? ( ) : null} {displayMode} {modeOptions.map((mode) => { const visuals = getModeVisuals(provider, mode.id); const Icon = visuals?.icon ? MODE_ICONS[visuals.icon] : ShieldCheck; return ( onSelectMode?.(mode.id)} leading={} > {mode.label} ); })} ) : null} {features?.map((feature) => { if (feature.type === "toggle") { const FeatureIcon = getFeatureIcon(feature.icon); return ( onSetFeature?.(feature.id, !feature.value)} style={({ pressed }) => [ styles.sheetSelect, pressed && styles.sheetSelectPressed, disabled && styles.disabledSheetSelect, ]} accessibilityRole="button" accessibilityLabel={getFeatureTooltip(feature)} testID={`agent-feature-${feature.id}`} > {feature.label} {feature.value ? "On" : "Off"} ); } if (feature.type === "select") { const selectedOption = feature.options.find((o) => o.id === feature.value); return ( [ styles.sheetSelect, pressed && styles.sheetSelectPressed, disabled && styles.disabledSheetSelect, ]} accessibilityRole="button" accessibilityLabel={getFeatureTooltip(feature)} testID={`agent-feature-${feature.id}`} > {selectedOption?.label ?? feature.label} {feature.options.map((option) => ( onSetFeature?.(feature.id, option.id)} > {option.label} ))} ); } return null; })} )} ); } const EMPTY_MODES: AgentMode[] = []; export function AgentStatusBar({ agentId, serverId, onDropdownClose }: AgentStatusBarProps) { const { preferences, updatePreferences } = useFormPreferences(); const agent = useSessionStore( useShallow((state) => { const currentAgent = state.sessions[serverId]?.agents?.get(agentId) ?? null; return currentAgent ? { provider: currentAgent.provider, cwd: currentAgent.cwd, currentModeId: currentAgent.currentModeId, runtimeModelId: currentAgent.runtimeInfo?.model ?? null, model: currentAgent.model, features: currentAgent.features, thinkingOptionId: currentAgent.thinkingOptionId, } : null; }), ); const availableModes = useStoreWithEqualityFn( useSessionStore, (state) => state.sessions[serverId]?.agents?.get(agentId)?.availableModes ?? EMPTY_MODES, (a, b) => a === b || JSON.stringify(a) === JSON.stringify(b), ); const client = useSessionStore((state) => state.sessions[serverId]?.client ?? null); const modelsQuery = useQuery({ queryKey: ["providerModels", serverId, agent?.provider ?? "__missing_provider__"], enabled: Boolean(client && agent?.provider), staleTime: 5 * 60 * 1000, queryFn: async () => { if (!client || !agent) { throw new Error("Daemon client unavailable"); } const payload = await client.listProviderModels(agent.provider, { cwd: agent.cwd }); if (payload.error) { throw new Error(payload.error); } return payload.models ?? []; }, }); const agentProviderDefinitions = useMemo(() => { const definition = AGENT_PROVIDER_DEFINITIONS.find((d) => d.id === agent?.provider); return definition ? [definition] : []; }, [agent?.provider]); const agentProviderModelQuery = useQuery({ queryKey: ["providerModels", serverId, agent?.provider, agent?.cwd ?? ""], enabled: Boolean(client && agent?.cwd && agent?.provider), staleTime: 5 * 60 * 1000, queryFn: async () => { if (!client || !agent) { throw new Error("Daemon client unavailable"); } const payload = await client.listProviderModels(agent.provider, { cwd: agent.cwd }); if (payload.error) { throw new Error(payload.error); } return payload.models ?? []; }, }); const agentProviderModels = useMemo(() => { const map = new Map(); if (agent?.provider && agentProviderModelQuery.data) { map.set(agent.provider, agentProviderModelQuery.data); } return map; }, [agent?.provider, agentProviderModelQuery.data]); const models = modelsQuery.data ?? null; const displayMode = availableModes.find((mode) => mode.id === agent?.currentModeId)?.label || agent?.currentModeId || "default"; const modelSelection = resolveAgentModelSelection({ models, runtimeModelId: agent?.runtimeModelId, configuredModelId: agent?.model, explicitThinkingOptionId: agent?.thinkingOptionId, }); const modeOptions = useMemo(() => { return availableModes.map((mode) => ({ id: mode.id, label: mode.label, })); }, [availableModes]); const modelOptions = useMemo(() => { return (models ?? []).map((model) => ({ id: model.id, label: model.label })); }, [models]); const favoriteKeys = useMemo( () => new Set((preferences.favoriteModels ?? []).map((favorite) => buildFavoriteModelKey(favorite))), [preferences.favoriteModels], ); const thinkingOptions = useMemo(() => { return (modelSelection.thinkingOptions ?? []).map((option) => ({ id: option.id, label: option.label, })); }, [modelSelection.thinkingOptions]); if (!agent) { return null; } return ( 0 ? modeOptions : [{ id: agent.currentModeId ?? "", label: displayMode }] } selectedModeId={agent.currentModeId ?? undefined} providerDefinitions={agentProviderDefinitions} allProviderModels={agentProviderModels} onSelectMode={(modeId) => { if (!client) { return; } void client.setAgentMode(agentId, modeId).catch((error) => { console.warn("[AgentStatusBar] setAgentMode failed", error); }); }} modelOptions={modelOptions} selectedModelId={modelSelection.activeModelId ?? undefined} onSelectModel={(modelId) => { if (!client) { return; } void updatePreferences( mergeProviderPreferences({ preferences, provider: agent.provider, updates: { model: modelId, }, }), ).catch((error) => { console.warn("[AgentStatusBar] persist model preference failed", error); }); void client.setAgentModel(agentId, modelId).catch((error) => { console.warn("[AgentStatusBar] setAgentModel failed", error); }); }} favoriteKeys={favoriteKeys} onToggleFavoriteModel={(provider, modelId) => { void updatePreferences(toggleFavoriteModel({ preferences, provider, modelId })).catch((error) => { console.warn("[AgentStatusBar] toggle favorite model failed", error); }); }} thinkingOptions={thinkingOptions.length > 1 ? thinkingOptions : undefined} selectedThinkingOptionId={modelSelection.selectedThinkingId ?? undefined} onSelectThinkingOption={(thinkingOptionId) => { if (!client) { return; } const activeModelId = modelSelection.activeModelId; if (activeModelId) { void updatePreferences( mergeProviderPreferences({ preferences, provider: agent.provider, updates: { model: activeModelId, thinkingByModel: { [activeModelId]: thinkingOptionId, }, }, }), ).catch((error) => { console.warn("[AgentStatusBar] persist thinking preference failed", error); }); } void client.setAgentThinkingOption(agentId, thinkingOptionId).catch((error) => { console.warn("[AgentStatusBar] setAgentThinkingOption failed", error); }); }} features={agent.features} onSetFeature={(featureId, value) => { if (!client) { return; } void client.setAgentFeature(agentId, featureId, value).catch((error) => { console.warn("[AgentStatusBar] setAgentFeature failed", error); }); }} isModelLoading={isProviderModelsQueryLoading(modelsQuery)} onDropdownClose={onDropdownClose} disabled={!client} /> ); } export function DraftAgentStatusBar({ providerDefinitions, selectedProvider, onSelectProvider, modeOptions, selectedMode, onSelectMode, models, selectedModel, onSelectModel, isModelLoading, allProviderModels, isAllModelsLoading, onSelectProviderAndModel, thinkingOptions, selectedThinkingOptionId, onSelectThinkingOption, features, onSetFeature, onDropdownClose, disabled = false, }: DraftAgentStatusBarProps) { const isWeb = Platform.OS === "web"; const { preferences, updatePreferences } = useFormPreferences(); const mappedModeOptions = useMemo(() => { if (modeOptions.length === 0) { return [{ id: "", label: "Default" }]; } return modeOptions.map((mode) => ({ id: mode.id, label: mode.label, })); }, [modeOptions]); const mappedThinkingOptions = useMemo(() => { return thinkingOptions.map((option) => ({ id: option.id, label: option.label })); }, [thinkingOptions]); const favoriteKeys = useMemo( () => new Set((preferences.favoriteModels ?? []).map((favorite) => buildFavoriteModelKey(favorite))), [preferences.favoriteModels], ); const effectiveSelectedMode = selectedMode || mappedModeOptions[0]?.id || ""; const effectiveSelectedThinkingOption = selectedThinkingOptionId || mappedThinkingOptions[0]?.id || undefined; if (isWeb) { return ( { void updatePreferences(toggleFavoriteModel({ preferences, provider, modelId })).catch((error) => { console.warn("[DraftAgentStatusBar] toggle favorite model failed", error); }); }} isLoading={isAllModelsLoading} disabled={disabled} onClose={onDropdownClose} /> 0 ? mappedThinkingOptions : undefined} selectedThinkingOptionId={effectiveSelectedThinkingOption} onSelectThinkingOption={onSelectThinkingOption} features={features} onSetFeature={onSetFeature} onDropdownClose={onDropdownClose} disabled={disabled} /> ); } const modelOptions: StatusOption[] = models.map((model) => ({ id: model.id, label: model.label, })); return ( <> onSelectModel(modelId)} isModelLoading={isAllModelsLoading} favoriteKeys={favoriteKeys} onToggleFavoriteModel={(provider, modelId) => { void updatePreferences(toggleFavoriteModel({ preferences, provider, modelId })).catch((error) => { console.warn("[DraftAgentStatusBar] toggle favorite model failed", error); }); }} thinkingOptions={mappedThinkingOptions.length > 0 ? mappedThinkingOptions : undefined} selectedThinkingOptionId={effectiveSelectedThinkingOption} onSelectThinkingOption={onSelectThinkingOption} features={features} onSetFeature={onSetFeature} disabled={disabled} /> ); } const styles = StyleSheet.create((theme) => ({ container: { flexDirection: "row", alignItems: "flex-end", gap: theme.spacing[1], }, modeBadge: { height: 28, flexDirection: "row", alignItems: "center", backgroundColor: "transparent", gap: theme.spacing[1], paddingHorizontal: theme.spacing[2], borderRadius: theme.borderRadius["2xl"], }, modeIconBadge: { width: 28, height: 28, alignItems: "center", justifyContent: "center", backgroundColor: "transparent", borderRadius: theme.borderRadius.full, }, modeBadgeHovered: { backgroundColor: theme.colors.surface2, }, modeBadgePressed: { backgroundColor: theme.colors.surface0, }, disabledBadge: { opacity: 0.5, }, modeBadgeText: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.normal, }, tooltipText: { color: theme.colors.foreground, fontSize: theme.fontSize.sm, lineHeight: theme.fontSize.sm * 1.4, }, prefsButton: { height: 28, flexDirection: "row", alignItems: "center", gap: theme.spacing[1], paddingHorizontal: theme.spacing[2], borderRadius: theme.borderRadius["2xl"], }, prefsButtonPressed: { backgroundColor: theme.colors.surface0, }, prefsButtonText: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.normal, flexShrink: 1, }, sheetSection: { gap: theme.spacing[2], }, sheetSelect: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: theme.spacing[3], paddingHorizontal: theme.spacing[4], paddingVertical: theme.spacing[3], borderRadius: theme.borderRadius.lg, borderWidth: 1, borderColor: theme.colors.surface2, backgroundColor: theme.colors.surface0, }, sheetSelectPressed: { backgroundColor: theme.colors.surface2, }, disabledSheetSelect: { opacity: 0.5, }, sheetSelectText: { flex: 1, color: theme.colors.foreground, fontSize: theme.fontSize.base, fontWeight: theme.fontWeight.semibold, }, }));