import type { ReactNode } from 'react' import { View, Text, Pressable, StyleSheet } from 'react-native' import { Check } from 'lucide-react-native' import { colors, spacing, typography } from '../theme/mobile-theme' import { BottomDrawer } from './BottomDrawer' export type PickerOption = { value: T label: string subtitle?: string disabled?: boolean renderIcon?: (selected: boolean) => ReactNode } type Props = { visible: boolean title: string options: PickerOption[] selected: T onSelect: (value: T) => void onLongSelect?: (value: T) => void onClose: () => void zIndex?: number } type PickerModalContentProps = Pick< Props, 'options' | 'selected' | 'onSelect' | 'onLongSelect' | 'onClose' > export function PickerModal({ visible, title, options, selected, onSelect, onLongSelect, onClose, zIndex }: Props) { return ( {title} ) } function PickerModalContent({ options, selected, onSelect, onLongSelect, onClose }: PickerModalContentProps) { // Why: closed BottomDrawer instances return null, so keeping option rows in // this child avoids rebuilding hidden picker contents on every parent render. return ( {options.map((opt, i) => { const isSelected = opt.value === selected return ( {i > 0 && } [ styles.row, pressed && !opt.disabled && styles.rowPressed, opt.disabled && styles.rowDisabled ]} onPress={() => { if (opt.disabled) { return } onSelect(opt.value) onClose() }} onLongPress={ onLongSelect ? () => { if (opt.disabled) { return } onLongSelect(opt.value) onClose() } : undefined } > {opt.renderIcon ? ( {opt.renderIcon(isSelected)} ) : null} {opt.label} {opt.subtitle ? {opt.subtitle} : null} {isSelected && } ) })} ) } const styles = StyleSheet.create({ header: { paddingHorizontal: spacing.xs, paddingBottom: spacing.sm }, title: { fontSize: 13, fontWeight: '500', color: colors.textMuted }, group: { backgroundColor: colors.bgPanel, borderRadius: 12, overflow: 'hidden' }, separator: { height: StyleSheet.hairlineWidth, backgroundColor: colors.borderSubtle, marginHorizontal: spacing.md }, row: { flexDirection: 'row', alignItems: 'center', paddingVertical: spacing.md, paddingHorizontal: spacing.md + 2 }, rowPressed: { backgroundColor: colors.bgRaised }, rowDisabled: { opacity: 0.45 }, rowContent: { flex: 1, minWidth: 0 }, rowIcon: { width: 22, alignItems: 'center', marginRight: spacing.sm }, rowLabel: { fontSize: typography.bodySize, color: colors.textPrimary }, rowLabelSelected: { fontWeight: '600' }, rowSubtitle: { fontSize: 11, color: colors.textMuted, marginTop: 1 } })