Skip to content

Commit

Permalink
feat: new slider system
Browse files Browse the repository at this point in the history
  • Loading branch information
Vali-98 committed Dec 18, 2024
1 parent 74f04b9 commit b46baba
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
12 changes: 11 additions & 1 deletion app/ComponentTest.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import DropdownSheet from '@components/DropdownSheet'
import MultiDropdownSheet from '@components/MultiDropdownSheet'
import SliderInput from '@components/SliderInput'
import React, { useState } from 'react'
import { View } from 'react-native'

Expand All @@ -17,7 +18,7 @@ const data = [

const ComponentTest = () => {
const [selected, setSelected] = useState<typeof data>([])

const [slider, setSlider] = useState(0)
return (
<View style={{ flex: 1, padding: 16 }}>
<MultiDropdownSheet
Expand All @@ -30,6 +31,15 @@ const ComponentTest = () => {
modalTitle="Test Selector"
search
/>
<SliderInput
value={slider}
onValueChange={setSlider}
label="Slider Test"
step={1}
min={0}
max={30}
precision={1}
/>
</View>
)
}
Expand Down
124 changes: 124 additions & 0 deletions app/components/SliderInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import Slider from '@react-native-community/slider'
import { Style } from 'constants/Global'
import { useState } from 'react'
import { View, Text, StyleSheet, TextInput } from 'react-native'

type SliderInputProps = {
label: string
value: number
onValueChange: (value: number) => void
min?: number
max?: number
step?: number
precision?: number
showInput?: boolean
disabled?: boolean
}

const clamp = (val: number, min: number, max: number, precision: number) =>
Math.min(Math.max(parseFloat(val?.toFixed(precision) ?? 0), min), max)

const SliderInput: React.FC<SliderInputProps> = ({
label,
value,
onValueChange,
min = 0,
max = 1,
step = 0,
precision = 0,
showInput = true,
disabled = false,
}) => {
const [textValue, setTextValue] = useState(value.toString())

const handleSliderChange = (v: number) => {
if (!isNaN(clamp(v, min, max, precision))) onValueChange(v)
setTextValue(value.toString())
}

const handleTextInputChange = (t: string) => {
let v = 0
setTextValue(t)
v = parseFloat(t)

if (!isNaN(v)) onValueChange(clamp(v, min, max, precision))
}

const handleEndEdit = () => {
const v = parseFloat(textValue)
if (!isNaN(v)) onValueChange(clamp(v, min, max, precision))
setTextValue(value.toString())
}

return (
<View style={{ alignItems: `center` }}>
<Text style={disabled ? styles.itemNameDisabled : styles.itemName}>{label}</Text>
<View style={styles.sliderContainer}>
<Slider
disabled={disabled}
style={styles.slider}
step={step}
minimumValue={min}
maximumValue={max}
value={value}
onSlidingComplete={handleSliderChange}
minimumTrackTintColor={Style.getColor('primary-surface4')}
maximumTrackTintColor={Style.getColor('primary-surface3')}
thumbTintColor={Style.getColor('primary-brand')}
/>
{showInput && (
<TextInput
editable={!disabled}
style={disabled ? styles.textBoxDisabled : styles.textBox}
value={textValue}
onChangeText={handleTextInputChange}
keyboardType="number-pad"
submitBehavior="blurAndSubmit"
onEndEditing={handleEndEdit}
onSubmitEditing={handleEndEdit}
onBlur={handleEndEdit}
/>
)}
</View>
</View>
)
}

export default SliderInput

const styles = StyleSheet.create({
itemName: {
color: Style.getColor('primary-text1'),
},

itemNameDisabled: {
color: Style.getColor('primary-text3'),
},

sliderContainer: {
flexDirection: `row`,
},

slider: {
flex: 9,
height: 40,
},

textBox: {
borderColor: Style.getColor('primary-surface4'),
color: Style.getColor('primary-text1'),
borderWidth: 1,
borderRadius: 12,
flex: 1.5,
textAlign: `center`,
},

textBoxDisabled: {
borderColor: Style.getColor('primary-surface4'),
color: Style.getColor('primary-text3'),
borderWidth: 1,
borderRadius: 12,
flex: 1.5,
textAlign: `center`,
},
})

0 comments on commit b46baba

Please sign in to comment.