Skip to content

Commit 43bed80

Browse files
feat: added disabled mode
1 parent c1080f7 commit 43bed80

File tree

5 files changed

+82
-39
lines changed

5 files changed

+82
-39
lines changed

src/sliders/range-slider/RangeSlider.component.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import {GestureDetector} from 'react-native-gesture-handler';
44
import {type LayoutChangeEvent, type ViewProps, type StyleProp, type ViewStyle, type TextStyle} from 'react-native';
55

66
import {styles} from './range-slider.styles';
7-
import {useTheme} from '../../theme/useTheme.hook';
87
import {useRangeSlider} from './useRangeSlider.hook';
8+
import {useSliderColors} from '../use-slider-colors.hook';
99
import {SliderTrack} from '../ui/slider-track/SliderTrack.component';
1010
import {useRangeSliderTrackPoints} from './useRangeSliderTrackPoints.hook';
1111
import {SliderIndicator} from '../ui/slider-indicator/SliderIndicator.component';
@@ -19,6 +19,7 @@ export interface RangeSliderProps extends ViewProps {
1919
step?: number;
2020
damping?: number;
2121
centered?: boolean;
22+
disabled?: boolean;
2223

2324
valueHeight?: number;
2425
thumbWidthActive?: number;
@@ -43,6 +44,7 @@ export const RangeSlider: React.FC<RangeSliderProps> = ({
4344
range = [0, 0],
4445
damping = 20,
4546
centered = false,
47+
disabled = false,
4648

4749
thumbStyle,
4850
valueStyle,
@@ -61,7 +63,7 @@ export const RangeSlider: React.FC<RangeSliderProps> = ({
6163
style,
6264
...props
6365
}) => {
64-
const {primary, secondaryContainer} = useTheme();
66+
const {filledTrackColor, remainingTrackColor} = useSliderColors(disabled, centered);
6567

6668
const trackPoints = useRangeSliderTrackPoints({max, min, step, centered});
6769
const {
@@ -90,32 +92,35 @@ export const RangeSlider: React.FC<RangeSliderProps> = ({
9092
<SliderTrackPoint
9193
key={pointValue}
9294
value={pointValue}
95+
disabled={disabled}
9396
selectedValue={selectedRange}
9497
onPress={slideToTrackPoint}
95-
style={[{backgroundColor: secondaryContainer.text}, trackPointStyle]}
98+
style={trackPointStyle}
9699
/>
97100
);
98101

99102
return (
100-
<GestureDetector gesture={gesture}>
103+
<GestureDetector gesture={gesture.enabled(!disabled)}>
101104
<View style={[styles.container, style]} onLayout={handleLayoutChange} {...props}>
102105
<SliderTrack
103-
style={[{backgroundColor: secondaryContainer.background}, styles.remainingBeforeTrack, remainingTrackBeforeAnimatedStyle, filledTrackStyle]}
106+
style={[{backgroundColor: remainingTrackColor}, styles.remainingBeforeTrack, remainingTrackBeforeAnimatedStyle, filledTrackStyle]}
104107
/>
105108
<SliderIndicator
106109
animValueProps={animMinValueProps}
107110
sliding={thumbMinSliding}
111+
disabled={disabled}
108112
style={[styles.thumb, indicatorStyle]}
109113
thumbStyle={thumbStyle}
110114
valueStyle={valueStyle}
111115
valueHeight={valueHeight}
112116
thumbWidthActive={thumbWidthActive}
113117
thumbWidthInactive={thumbWidthInactive}
114118
/>
115-
<SliderTrack style={[{backgroundColor: primary.background}, styles.filledTrack, filledTrackAnimatedStyle, filledTrackStyle]} />
119+
<SliderTrack style={[{backgroundColor: filledTrackColor}, styles.filledTrack, filledTrackAnimatedStyle, filledTrackStyle]} />
116120
<SliderIndicator
117121
animValueProps={animMaxValueProps}
118122
sliding={thumbMaxSliding}
123+
disabled={disabled}
119124
style={[styles.thumb, indicatorStyle]}
120125
thumbStyle={thumbStyle}
121126
valueStyle={valueStyle}
@@ -124,12 +129,7 @@ export const RangeSlider: React.FC<RangeSliderProps> = ({
124129
thumbWidthInactive={thumbWidthInactive}
125130
/>
126131
<SliderTrack
127-
style={[
128-
{backgroundColor: secondaryContainer.background},
129-
styles.remainingAfterTrack,
130-
remainingTrackAfterAnimatedStyle,
131-
remainingTrackStyle,
132-
]}
132+
style={[{backgroundColor: remainingTrackColor}, styles.remainingAfterTrack, remainingTrackAfterAnimatedStyle, remainingTrackStyle]}
133133
/>
134134
<View style={[styles.trackPoints, trackPointsStyle]}>{trackPoints.map(renderTrackPoint)}</View>
135135
</View>

src/sliders/slider /Slider.component.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import {type LayoutChangeEvent, type ViewProps, type StyleProp, type ViewStyle,
55

66
import {styles} from './slider.styles';
77
import {useSlider} from './useSlider.hook';
8-
import {useTheme} from '../../theme/useTheme.hook';
98
import {useSliderTrackPoints} from './useSliderTrackPoints.hook';
109
import {SliderTrack} from '../ui/slider-track/SliderTrack.component';
1110
import {SliderIndicator} from '../ui/slider-indicator/SliderIndicator.component';
1211
import {SliderTrackPoint} from '../ui/slider-track-point/SliderTrackPoint.component';
12+
import {useSliderColors} from '../use-slider-colors.hook';
1313

1414
export interface SliderProps extends ViewProps {
1515
max: number;
@@ -18,6 +18,7 @@ export interface SliderProps extends ViewProps {
1818
value?: number;
1919
step?: number;
2020
centered?: boolean;
21+
disabled?: boolean;
2122
damping?: number;
2223

2324
valueHeight?: number;
@@ -42,6 +43,7 @@ export const Slider: React.FC<SliderProps> = ({
4243
step,
4344
value = 0,
4445
damping = 20,
46+
disabled = false,
4547
centered = false,
4648

4749
thumbStyle,
@@ -61,7 +63,7 @@ export const Slider: React.FC<SliderProps> = ({
6163
style,
6264
...props
6365
}) => {
64-
const {primary, secondaryContainer} = useTheme();
66+
const {filledTrackColor, remainingTrackColor} = useSliderColors(disabled, centered);
6567

6668
const trackPoints = useSliderTrackPoints({max, min, step, centered});
6769
const {
@@ -88,27 +90,22 @@ export const Slider: React.FC<SliderProps> = ({
8890
const renderTrackPoint = (pointValue: number) => (
8991
<SliderTrackPoint
9092
key={pointValue}
91-
selectedValue={selectedValue}
9293
value={pointValue}
94+
selectedValue={selectedValue}
95+
disabled={disabled}
9396
onPress={slideToTrackPoint}
9497
disableColorChange={centered}
9598
style={trackPointStyle}
9699
/>
97100
);
98101

99102
return (
100-
<GestureDetector gesture={gesture}>
103+
<GestureDetector gesture={gesture.enabled(!disabled)}>
101104
<View style={[styles.container, style]} onLayout={handleLayoutChange} {...props}>
102-
<SliderTrack
103-
style={[
104-
{backgroundColor: centered ? secondaryContainer.background : primary.background},
105-
styles.filledTrack,
106-
filledTrackAnimatedStyle,
107-
filledTrackStyle,
108-
]}
109-
/>
105+
<SliderTrack style={[{backgroundColor: filledTrackColor}, styles.filledTrack, filledTrackAnimatedStyle, filledTrackStyle]} />
110106
<SliderIndicator
111107
sliding={sliding}
108+
disabled={disabled}
112109
animValueProps={animValueProps}
113110
style={[styles.thumb, indicatorStyle]}
114111
thumbStyle={thumbStyle}
@@ -117,9 +114,7 @@ export const Slider: React.FC<SliderProps> = ({
117114
thumbWidthActive={thumbWidthActive}
118115
thumbWidthInactive={thumbWidthInactive}
119116
/>
120-
<SliderTrack
121-
style={[{backgroundColor: secondaryContainer.background}, styles.remainingTrack, remainingTrackAnimatedStyle, remainingTrackStyle]}
122-
/>
117+
<SliderTrack style={[{backgroundColor: remainingTrackColor}, styles.remainingTrack, remainingTrackAnimatedStyle, remainingTrackStyle]} />
123118
<View style={[styles.trackPoints, {justifyContent: trackPointsJustifyContent}, trackPointsStyle]}>{trackPoints.map(renderTrackPoint)}</View>
124119
</View>
125120
</GestureDetector>

src/sliders/ui/slider-indicator/SliderIndicator.component.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React from 'react';
1+
import React, {useMemo} from 'react';
22
import Animated, {interpolate, useAnimatedStyle, type AnimatedProps, type SharedValue} from 'react-native-reanimated';
33
import {View, TextInput, type ViewProps, type TextInputProps, type StyleProp, type ViewStyle, type TextStyle} from 'react-native';
44

55
import {styles} from './slider-indicator.styles';
66
import {useTheme} from '../../../theme/useTheme.hook';
7+
import {convertToRGBA} from '../../../utils/convert-to-rgba';
78
import {useTypography} from '../../../typography/useTypography.component';
89

910
interface SliderIndicatorProps extends ViewProps {
11+
disabled: boolean;
1012
sliding: SharedValue<number>;
1113
animValueProps: AnimatedProps<Pick<TextInputProps, 'value' | 'defaultValue'>>;
1214

@@ -23,8 +25,10 @@ const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
2325
const THUMB_VALUE_GAP = 4;
2426

2527
export const SliderIndicator: React.FC<SliderIndicatorProps> = ({
26-
animValueProps,
2728
sliding,
29+
disabled,
30+
animValueProps,
31+
2832
thumbStyle,
2933
valueStyle,
3034
valueHeight = 44,
@@ -35,6 +39,8 @@ export const SliderIndicator: React.FC<SliderIndicatorProps> = ({
3539
const {labelLarge} = useTypography();
3640
const {surface, primary} = useTheme();
3741

42+
const disabledColor = useMemo(() => convertToRGBA(surface.text as string, 0.38), [surface.text]);
43+
3844
const valueAnimatedStyle = useAnimatedStyle(() => {
3945
const topActive = -valueHeight - THUMB_VALUE_GAP;
4046

@@ -66,7 +72,7 @@ export const SliderIndicator: React.FC<SliderIndicatorProps> = ({
6672
valueStyle,
6773
]}
6874
/>
69-
<Animated.View style={[styles.thumb, {backgroundColor: primary.background}, thumbAnimatedStyle, thumbStyle]} />
75+
<Animated.View style={[styles.thumb, {backgroundColor: disabled ? disabledColor : primary.background}, thumbAnimatedStyle, thumbStyle]} />
7076
</View>
7177
);
7278
};

src/sliders/ui/slider-track-point/SliderTrackPoint.component.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React from 'react';
1+
import React, {useMemo} from 'react';
22
import Animated, {useAnimatedStyle, type SharedValue} from 'react-native-reanimated';
33
import {Pressable, type PressableProps, type StyleProp, type ViewStyle} from 'react-native';
44

55
import {styles} from './slider-track-point.styles';
66
import {useTheme} from '../../../theme/useTheme.hook';
7+
import {convertToRGBA} from '../../../utils/convert-to-rgba';
78

89
interface SliderTrackProps extends Omit<PressableProps, 'onPress'> {
910
value: number;
11+
disabled: boolean;
1012
selectedValue: SharedValue<number> | SharedValue<number[]>;
1113

1214
style?: StyleProp<ViewStyle>;
@@ -17,21 +19,40 @@ interface SliderTrackProps extends Omit<PressableProps, 'onPress'> {
1719

1820
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
1921

20-
export const SliderTrackPoint: React.FC<SliderTrackProps> = ({value, selectedValue, disableColorChange = false, onPress, style, ...props}) => {
21-
const {secondaryContainer} = useTheme();
22+
export const SliderTrackPoint: React.FC<SliderTrackProps> = ({
23+
value,
24+
disabled,
25+
selectedValue,
26+
disableColorChange = false,
27+
onPress,
28+
style,
29+
...props
30+
}) => {
31+
const {secondaryContainer, surface} = useTheme();
2232

23-
const handleTrackPointPress = () => onPress(value);
33+
const [selectedTrackPointColor, unselectedTrackPointColor] = useMemo(
34+
() =>
35+
disabled
36+
? [convertToRGBA(surface.textInverse as string, 0.66), convertToRGBA(surface.text as string, 0.38)]
37+
: [secondaryContainer.background, secondaryContainer.text],
38+
[disabled, surface]
39+
);
2440

25-
const trackPointAnimatedStyle = useAnimatedStyle(() => ({
26-
backgroundColor:
27-
!disableColorChange && isTrackPointSelected(value, selectedValue.value) ? secondaryContainer.background : secondaryContainer.text,
28-
}));
41+
const trackPointAnimatedColorStyle = useAnimatedStyle(
42+
() => ({
43+
backgroundColor: !disableColorChange && isTrackPointSelected(value, selectedValue.value) ? selectedTrackPointColor : unselectedTrackPointColor,
44+
}),
45+
[disableColorChange, value, selectedTrackPointColor, unselectedTrackPointColor]
46+
);
47+
48+
const handleTrackPointPress = () => onPress(value);
2949

3050
return (
3151
<AnimatedPressable
3252
hitSlop={16}
3353
onPress={handleTrackPointPress}
34-
style={[styles.trackPoint, {backgroundColor: secondaryContainer.text}, trackPointAnimatedStyle, style]}
54+
style={[styles.trackPoint, trackPointAnimatedColorStyle, style]}
55+
disabled={disabled}
3556
{...props}
3657
/>
3758
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {useMemo} from 'react';
2+
import {useTheme} from '../theme/useTheme.hook';
3+
import {convertToRGBA} from '../utils/convert-to-rgba';
4+
5+
export const useSliderColors = (disabled: boolean, centered: boolean) => {
6+
const theme = useTheme();
7+
8+
const [filledTrackColor, remainingTrackColor] = useMemo(() => {
9+
const disabledRemainingTrackColor = convertToRGBA(theme.surface.text as string, 0.12);
10+
const [enabledFilledTrackColor, disabledFilledTrackColor] = centered
11+
? [theme.secondaryContainer.background, disabledRemainingTrackColor]
12+
: [theme.primary.background, convertToRGBA(theme.surface.text as string, 0.38)];
13+
14+
return disabled ? [disabledFilledTrackColor, disabledRemainingTrackColor] : [enabledFilledTrackColor, theme.secondaryContainer.background];
15+
}, [disabled, centered, theme]);
16+
17+
return {
18+
filledTrackColor,
19+
remainingTrackColor,
20+
};
21+
};

0 commit comments

Comments
 (0)