import React from 'react'; import { View, StyleSheet, ViewStyle, } from 'react-native'; import { Text } from '@/components/ui/Text'; import Slider from '@react-native-community/slider'; import { useThemeColor } from '@/hooks/use-theme-color'; import { Theme } from '@/constants/theme'; type SliderVariant = 'rich' | 'compact'; interface ScaleSliderProps { label: string; value: number; onValueChange: (value: number) => void; onValueFormat?: (value: number) => string; min?: number; max?: number; step?: number; minLabel?: string; maxLabel?: string; icon?: React.ReactNode; // rich variant only showMax?: boolean; // shows "x/10" format instead of just "x" variant?: SliderVariant; style?: ViewStyle; } export const ScaleSlider: React.FC = ({ label, value, onValueChange, onValueFormat, min = 0, max = 10, step = 1, minLabel, maxLabel, icon, showMax, variant = 'compact', style, }) => { const textColor = useThemeColor({}, 'text'); const tintColor = useThemeColor({}, 'tint'); const trackingColor = useThemeColor({}, 'sliderTracking'); const sliderLabelsColor = useThemeColor({}, 'sliderLabels'); const isRich = variant === 'rich'; const valueDisplay = showMax || !isRich ? `${value}/${max}` : `${value}`; return ( {/* Header row */} {isRich && icon && ( {icon} )} {label} {(onValueFormat ? onValueFormat(value) : valueDisplay)} {/* XXX: Rich variant needs some extra margin to account for icons */} {/* Slider has a glitch with the full padding of it */} {/* Min / Max labels */} {(minLabel || maxLabel) && ( {minLabel && ( {minLabel.toUpperCase()} )} {maxLabel && ( {maxLabel.toUpperCase()} )} )} ); }; const styles = StyleSheet.create({ container: { width: '100%', }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, // Rich has bigger margin than compact headerRich: { marginBottom: 4, }, headerCompact: { marginBottom: 1 }, labelRow: { flexDirection: 'row', alignItems: 'center', gap: 8, }, iconWrapper: { justifyContent: 'center', alignItems: 'center', }, // Rich variant labelRich: { fontSize: 14, fontWeight: 500 }, valueRich: { fontSize: 18, lineHeight: 28, fontWeight: 600 }, // Compact variant labelCompact: { fontSize: 12, fontWeight: 600, lineHeight: 16 }, valueCompact: { fontSize: 12, lineHeight: 16, fontWeight: 600, color: Theme.colors.light.textSecondary, }, slider: { width: '100%', height: 40, }, rangeLabels: { flexDirection: 'row', justifyContent: 'space-between', marginTop: -4, }, rangeLabel: { ...Theme.typography.labelXs, fontWeight: 500, }, });