/** * CareSlider — a custom DISCRETE slider (pure React Native, no native module). * * The care check-in needs a moisture/growth "slider" but OTA can't add native * modules. This is a SEGMENTED slider: each level is a tappable block with its * own color (a BLOCKED gradient — each segment a distinct shade, not a smooth * blend), so it's both visually clear and reliable to use. Tap a segment to * select it. Labels are forced onto two lines (one word per line) for clarity. * * Props: * - levels: string[] — the labels, left→right (e.g. ['Very dry', ..., 'Really wet']) * - value: number — the currently selected index (0-based) * - onChange: (index: number) => void * - colors: string[] — one color per level (the blocked gradient), left→right */ import React from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; interface CareSliderProps { levels: string[]; /** Currently selected index, or -1 for nothing selected (no highlight). */ value: number; onChange: (index: number) => void; colors: string[]; } export function CareSlider({ levels, value, onChange, colors }: CareSliderProps) { const hasSelection = value >= 0; return ( {/* Segmented track — each level is a tappable block with its own shade. */} {levels.map((label, i) => { const selected = hasSelection && i === value; return ( onChange(i)} accessibilityLabel={label} > {selected ? : null} ); })} {/* Two-line labels — one word per line so every level reads the same. */} {levels.map((label, i) => { const words = label.split(' '); const selected = hasSelection && i === value; return ( {words.map((word, w) => ( {word} ))} ); })} ); } const s = StyleSheet.create({ wrap: { marginVertical: 6 }, track: { flexDirection: 'row', height: 34, borderRadius: 10, overflow: 'hidden', borderWidth: 1, borderColor: '#D8DCCB', }, segment: { flex: 1, alignItems: 'center', justifyContent: 'center', }, segmentFirst: { borderTopLeftRadius: 9, borderBottomLeftRadius: 9 }, segmentLast: { borderTopRightRadius: 9, borderBottomRightRadius: 9 }, segmentSelected: { // A slightly darker ring so the active block stands out. borderWidth: 2, borderColor: '#2D4A2D', }, thumb: { width: 18, height: 18, borderRadius: 9, backgroundColor: '#FFF', borderWidth: 2, borderColor: '#2D4A2D', shadowColor: '#000', shadowOpacity: 0.25, shadowRadius: 2, shadowOffset: { width: 0, height: 1 }, elevation: 2, }, labels: { flexDirection: 'row', marginTop: 8, }, labelCol: { flex: 1, alignItems: 'center', }, labelWord: { fontSize: 10, color: '#8A8571', fontWeight: '700', lineHeight: 12, textAlign: 'center', }, labelWordSelected: { color: '#1B2A4A', // navy — readable on the light segment shades fontWeight: '900', }, });