import React, { type ReactNode } from 'react'; import { ActivityIndicator, Image, Pressable, Text, View } from 'react-native'; import { Check, type LucideIcon } from 'lucide-react-native'; import { conversationStyles } from '../../features/conversation/conversationStyles'; import { themedColor } from '../../theme'; import { ToolWidgetRow } from '../primitives/ToolWidgetRow'; import { WidgetCard } from '../primitives/WidgetCard'; import { toolWidgetStyles } from '../primitives/toolWidgetStyles'; import type { ToolWidgetStatus } from '../toolWidgetUtils'; /** * Shared building blocks for the interactive widgets (clarifying questions, * agent permissions, payments) — the option rows, buttons and fallback/status * surfaces they all render. */ /** Radio/checkbox option row (clarifying options, provider picker, PSP selects). */ export function SelectableOptionRow({ centered = false, children, disabled, imageUrl, label, multi = false, onPress, selected, subtitle, }: { /** Centers the indicator against the whole row instead of the label's first line. */ centered?: boolean; children?: ReactNode; disabled: boolean; imageUrl?: string | null; /** Omit to let `children` (e.g. an inline input) stand in for the label instead. */ label?: string; multi?: boolean; onPress: () => void; selected: boolean; subtitle?: string | null; }) { return ( {multi ? ( // approvalCheckbox's marginTop is tuned for EntityApprovalBatchCard's rows; // here the 20px box already lines up with the 18px label line, so drop it. {selected ? : null} ) : ( {selected ? : null} )} {label ? {label} : null} {subtitle ? {subtitle} : null} {imageUrl ? : null} {children} ); } export function WidgetActionButton({ disabled, isSubmitting, label, onPress, primary = false, small = false, }: { disabled: boolean; isSubmitting: boolean; label: string; onPress: () => void; primary?: boolean; /** DS Button size="sm" instead of the default taller approval-card button. */ small?: boolean; }) { return ( {isSubmitting ? : null} {label} ); } /** * Card with a message and a single action — the web's amber fallback panels * (choices/fields failed to load) and the clarifying "couldn't generate * questions" state. */ export function FallbackActionCard({ buttonLabel, error, isSubmitting, message, onPress, }: { buttonLabel: string; error?: string | null; isSubmitting: boolean; message: string; onPress?: () => void; }) { return ( {message} {})} /> {error ? {error} : null} ); } /** Resolved-state row with the tool's error message underneath (PSP widgets). */ export function StatusRowWithError({ errorMessage, icon, status, title, }: { errorMessage: string | null; icon: LucideIcon; status: ToolWidgetStatus; title: string; }) { return ( {errorMessage ? {errorMessage} : null} ); } /** DS tiny ghost icon button (pager chevrons, the clarifying card's minimize toggle). */ export function TinyIconButton({ accessibilityLabel, disabled, icon: Icon, onPress, }: { accessibilityLabel: string; disabled: boolean; icon: LucideIcon; onPress: () => void; }) { return ( ); }