Skip to content

Commit 4e94a10

Browse files
authored
Moved GradientSlider to FC. (#2834)
* Started moving GradientSlider to FC * Fixed switch case * More changes * Changes to gradient slider * Added forward ref to the gradient slider * Added useCallbacks * Added more useCallBacks * fixed lint error * Fixed ts errors * Removed ts-ingores from screens * Fixed type error with defaults of old slider * Reverting changes to ColorSliderGroup * Reverting changes to screens
1 parent 017a7cd commit 4e94a10

File tree

1 file changed

+137
-164
lines changed

1 file changed

+137
-164
lines changed
Lines changed: 137 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import _ from 'lodash';
22
import tinycolor from 'tinycolor2';
3-
import React, {Component} from 'react';
3+
import React, {useCallback, useEffect, useState} from 'react';
44
import {StyleProp, ViewStyle} from 'react-native';
55
import {Colors} from '../../style';
66
import {asBaseComponent, forwardRef, ForwardRefInjectedProps} from '../../commons/new';
@@ -19,7 +19,10 @@ export enum GradientSliderTypes {
1919
SATURATION = 'saturation'
2020
}
2121

22-
export type GradientSliderProps = Omit<SliderProps, 'onValueChange'> & {
22+
export type GradientSliderProps = Omit<
23+
SliderProps,
24+
'onValueChange' | 'value' | 'minimumValue' | 'maximumValue' | 'step' | 'thumbHitSlop' | 'useGap'
25+
> & {
2326
/**
2427
* The gradient color
2528
*/
@@ -48,196 +51,166 @@ export type GradientSliderProps = Omit<SliderProps, 'onValueChange'> & {
4851
* If true the Slider will be disabled and will appear in disabled color
4952
*/
5053
disabled?: boolean;
51-
};
54+
} & Partial<Pick<SliderProps, 'value' | 'minimumValue' | 'maximumValue' | 'step' | 'thumbHitSlop' | 'useGap'>>; // Fixes typing errors with the old slider.
5255

5356
type GradientSliderComponentProps = {
5457
/**
5558
* Context of the slider group
5659
*/
5760
sliderContext: SliderContextProps;
58-
} & GradientSliderProps &
59-
typeof defaultProps;
61+
} & GradientSliderProps;
6062

6163
type Props = GradientSliderComponentProps & ForwardRefInjectedProps;
6264

63-
interface GradientSliderState {
64-
color: tinycolor.ColorFormats.HSLA;
65-
initialColor: tinycolor.ColorFormats.HSLA;
66-
prevColor: string | undefined;
67-
}
68-
69-
const defaultProps = {
70-
type: GradientSliderTypes.DEFAULT,
71-
gradientSteps: 120,
72-
color: Colors.$backgroundPrimaryHeavy
73-
};
74-
7565
/**
7666
* @description: A Gradient Slider component
7767
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/SliderScreen.tsx
7868
* @gif: https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/GradientSlider/GradientSlider.gif?raw=true
7969
*/
80-
class GradientSlider extends Component<Props, GradientSliderState> {
81-
static displayName = 'GradientSlider';
82-
83-
static defaultProps = defaultProps;
84-
85-
static types = GradientSliderTypes;
86-
87-
constructor(props: Props) {
88-
super(props);
89-
90-
this.state = {
91-
prevColor: props.color,
92-
initialColor: Colors.getHSL(props.color),
93-
color: Colors.getHSL(props.color)
94-
};
95-
}
96-
97-
static getDerivedStateFromProps(nextProps: Props, prevState: GradientSliderState) {
98-
if (prevState.prevColor !== nextProps.color) {
99-
return {
100-
color: Colors.getHSL(nextProps.color),
101-
prevColor: Colors.getHSL(nextProps.color)
102-
};
103-
}
104-
return null;
105-
}
106-
107-
slider = React.createRef();
108-
109-
reset = () => {
110-
this.updateColor(this.state.initialColor);
111-
};
112-
113-
getColor() {
114-
const {color} = this.state;
115-
const {value} = this.props.sliderContext;
116-
117-
return value || color;
118-
}
119-
120-
getStepColor = (i: number) => {
121-
const color = this.getColor();
122-
return tinycolor({...color, a: i}).toHslString();
123-
};
124-
125-
renderDefaultGradient = () => {
126-
const color = this.getColor();
127-
const {gradientSteps} = this.props;
70+
const GradientSlider = (props: Props) => {
71+
const {
72+
type = GradientSliderTypes.DEFAULT,
73+
gradientSteps = 120,
74+
color: propsColors = Colors.$backgroundPrimaryHeavy,
75+
sliderContext,
76+
onValueChange: _onValueChange,
77+
migrate,
78+
containerStyle,
79+
disabled,
80+
accessible,
81+
forwardedRef,
82+
...others
83+
} = props;
84+
85+
const [initialColor] = useState(Colors.getHSL(propsColors));
86+
const [color, setColor] = useState(Colors.getHSL(propsColors));
87+
88+
useEffect(() => {
89+
setColor(Colors.getHSL(propsColors));
90+
}, [propsColors]);
91+
92+
const getColor = useCallback(() => {
93+
return color || sliderContext.value;
94+
}, [color, sliderContext.value]);
95+
96+
const renderDefaultGradient = useCallback(() => {
97+
const color = getColor();
12898

12999
return <Gradient color={color} numberOfSteps={gradientSteps}/>;
130-
};
131-
132-
renderHueGradient = () => {
133-
const {gradientSteps} = this.props;
100+
}, [getColor, gradientSteps]);
134101

102+
const renderHueGradient = useCallback(() => {
135103
return <Gradient type={Gradient.types.HUE} numberOfSteps={gradientSteps}/>;
136-
};
137-
138-
renderLightnessGradient = () => {
139-
const color = this.getColor();
140-
const {gradientSteps} = this.props;
104+
}, [gradientSteps]);
141105

106+
const renderLightnessGradient = useCallback(() => {
107+
const color = getColor();
142108
return <Gradient type={Gradient.types.LIGHTNESS} color={color} numberOfSteps={gradientSteps}/>;
143-
};
144-
145-
renderSaturationGradient = () => {
146-
const color = this.getColor();
147-
const {gradientSteps} = this.props;
109+
}, [getColor, gradientSteps]);
148110

111+
const renderSaturationGradient = useCallback(() => {
112+
const color = getColor();
149113
return <Gradient type={Gradient.types.SATURATION} color={color} numberOfSteps={gradientSteps}/>;
150-
};
114+
}, [getColor, gradientSteps]);
151115

152-
onValueChange = (value: string, alpha: number) => {
116+
const onValueChange = useCallback((value: string, alpha: number) => {
153117
// alpha returns for type.DEFAULT
154-
this.props.onValueChange?.(value, alpha);
155-
};
118+
_onValueChange?.(value, alpha);
119+
},
120+
[_onValueChange]);
156121

157-
updateColor(color: tinycolor.ColorFormats.HSLA) {
158-
if (!_.isEmpty(this.props.sliderContext)) {
159-
this.props.sliderContext.setValue?.(color);
122+
const updateColor = useCallback((color: tinycolor.ColorFormats.HSLA) => {
123+
if (!_.isEmpty(sliderContext)) {
124+
sliderContext.setValue?.(color);
160125
} else {
161-
this.setState({color});
126+
setColor(color);
162127
const hex = Colors.getHexString(color);
163-
this.onValueChange(hex, color.a);
128+
onValueChange(hex, color.a);
164129
}
130+
},
131+
[sliderContext, onValueChange]);
132+
133+
const reset = useCallback(() => {
134+
updateColor(initialColor);
135+
}, [initialColor, updateColor]);
136+
137+
const updateAlpha = useCallback((a: number) => {
138+
const color = getColor();
139+
updateColor({...color, a});
140+
},
141+
[getColor, updateColor]);
142+
143+
const updateHue = useCallback((h: number) => {
144+
const color = getColor();
145+
updateColor({...color, h});
146+
},
147+
[getColor, updateColor]);
148+
149+
const updateLightness = useCallback((l: number) => {
150+
const color = getColor();
151+
updateColor({...color, l});
152+
},
153+
[getColor, updateColor]);
154+
155+
const updateSaturation = useCallback((s: number) => {
156+
const color = getColor();
157+
updateColor({...color, s});
158+
},
159+
[getColor, updateColor]);
160+
161+
const _color = getColor();
162+
const thumbTintColor = Colors.getHexString(_color);
163+
let step = 0.01;
164+
let maximumValue = 1;
165+
let value = color.a;
166+
let renderTrack = renderDefaultGradient;
167+
let sliderOnValueChange = updateAlpha;
168+
169+
switch (type) {
170+
case GradientSliderTypes.HUE:
171+
step = 1;
172+
maximumValue = 359;
173+
value = initialColor.h;
174+
renderTrack = renderHueGradient;
175+
sliderOnValueChange = updateHue;
176+
break;
177+
case GradientSliderTypes.LIGHTNESS:
178+
value = initialColor.l;
179+
renderTrack = renderLightnessGradient;
180+
sliderOnValueChange = updateLightness;
181+
break;
182+
case GradientSliderTypes.SATURATION:
183+
value = initialColor.s;
184+
renderTrack = renderSaturationGradient;
185+
sliderOnValueChange = updateSaturation;
186+
break;
187+
default:
188+
break;
165189
}
190+
const SliderComponent = migrate ? NewSlider : Slider;
191+
192+
return (
193+
<SliderComponent
194+
{...others}
195+
//@ts-expect-error
196+
ref={forwardedRef}
197+
onReset={reset}
198+
renderTrack={renderTrack}
199+
step={step}
200+
maximumValue={maximumValue}
201+
value={value}
202+
thumbTintColor={thumbTintColor}
203+
onValueChange={sliderOnValueChange}
204+
containerStyle={containerStyle}
205+
disabled={disabled}
206+
accessible={accessible}
207+
useRange={false}
208+
/>
209+
);
210+
};
166211

167-
updateAlpha = (a: number) => {
168-
const color = this.getColor();
169-
this.updateColor({...color, a});
170-
};
171-
172-
updateHue = (h: number) => {
173-
const color = this.getColor();
174-
this.updateColor({...color, h});
175-
};
176-
177-
updateLightness = (l: number) => {
178-
const color = this.getColor();
179-
this.updateColor({...color, l});
180-
};
181-
182-
updateSaturation = (s: number) => {
183-
const color = this.getColor();
184-
this.updateColor({...color, s});
185-
};
186-
187-
render() {
188-
const {type, containerStyle, disabled, accessible, forwardedRef, migrate, ...others} = this.props;
189-
const initialColor = this.state.initialColor;
190-
const color = this.getColor();
191-
const thumbTintColor = Colors.getHexString(color);
192-
let step = 0.01;
193-
let maximumValue = 1;
194-
let value = color.a;
195-
let renderTrack = this.renderDefaultGradient;
196-
let onValueChange = this.updateAlpha;
197-
198-
switch (type) {
199-
case GradientSliderTypes.HUE:
200-
step = 1;
201-
maximumValue = 359;
202-
value = initialColor.h;
203-
renderTrack = this.renderHueGradient;
204-
onValueChange = this.updateHue;
205-
break;
206-
case GradientSliderTypes.LIGHTNESS:
207-
value = initialColor.l;
208-
renderTrack = this.renderLightnessGradient;
209-
onValueChange = this.updateLightness;
210-
break;
211-
case GradientSliderTypes.SATURATION:
212-
value = initialColor.s;
213-
renderTrack = this.renderSaturationGradient;
214-
onValueChange = this.updateSaturation;
215-
break;
216-
default:
217-
break;
218-
}
219-
220-
const SliderComponent = migrate ? NewSlider : Slider;
221-
222-
return (
223-
<SliderComponent
224-
{...others}
225-
//@ts-expect-error
226-
ref={forwardedRef}
227-
onReset={this.reset}
228-
renderTrack={renderTrack}
229-
step={step}
230-
maximumValue={maximumValue}
231-
value={value}
232-
thumbTintColor={thumbTintColor}
233-
onValueChange={onValueChange}
234-
containerStyle={containerStyle}
235-
disabled={disabled}
236-
accessible={accessible}
237-
useRange={false}
238-
/>
239-
);
240-
}
241-
}
212+
GradientSlider.displayName = 'GradientSlider';
213+
GradientSlider.types = GradientSliderTypes;
242214

243-
export default asBaseComponent<GradientSliderComponentProps, typeof GradientSlider>(forwardRef(asSliderGroupChild(GradientSlider)));
215+
// eslint-disable-next-line max-len
216+
export default asBaseComponent<GradientSliderProps, typeof GradientSlider>(forwardRef(asSliderGroupChild(forwardRef(GradientSlider))));

0 commit comments

Comments
 (0)