Skip to content

Commit 634df31

Browse files
authored
ColorPicker - fix - hue changes to red after move lightness to white (#2942)
* ColorPicker - fix types on subcomponents * clean types * ColorSliderGroup - replace asBaseComponent with useThemeProps hook
1 parent 2c81f44 commit 634df31

File tree

8 files changed

+72
-61
lines changed

8 files changed

+72
-61
lines changed

src/components/colorPicker/ColorPickerDialog.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import _ from 'lodash';
22
import React, {useCallback, useEffect, useState} from 'react';
33
import {LayoutAnimation, StyleSheet, Keyboard, StyleProp, ViewStyle} from 'react-native';
4-
54
import {Constants, asBaseComponent} from '../../commons/new';
65
import {Colors} from '../../style';
76
import {ModalProps} from '../../components/modal';
87
import Dialog, {DialogProps} from '../../incubator/Dialog';
9-
import {getColorValue, getValidColorString, getTextColor, BORDER_RADIUS} from './ColorPickerPresenter';
8+
import {getColorValue, getValidColorString, getTextColor, BORDER_RADIUS, HSLColor} from './ColorPickerPresenter';
109
import Header from './ColorPickerDialogHeader';
1110
import Preview from './ColorPickerPreview';
1211
import Sliders from './ColorPickerDialogSliders';
1312

14-
interface Props extends DialogProps {
13+
export interface ColorPickerDialogProps extends DialogProps {
1514
/**
1615
* The initial color to pass the picker dialog
1716
*/
@@ -45,7 +44,6 @@ interface Props extends DialogProps {
4544
*/
4645
migrate?: boolean;
4746
}
48-
export type ColorPickerDialogProps = Props;
4947

5048
const KEYBOARD_HEIGHT = 216;
5149
const MODAL_PROPS = {
@@ -57,7 +55,7 @@ const MODAL_PROPS = {
5755
* @extends: Dialog
5856
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/ColorPickerScreen.tsx
5957
*/
60-
const ColorPickerDialog = (props: Props) => {
58+
const ColorPickerDialog = (props: ColorPickerDialogProps) => {
6159
const {
6260
initialColor = Colors.$backgroundNeutralLight,
6361
dialogProps,
@@ -149,8 +147,9 @@ const ColorPickerDialog = (props: Props) => {
149147
setValid(valid);
150148
};
151149

152-
const updateColor = useCallback((hex: string) => {
153-
setColor(Colors.getHSL(hex));
150+
const updateColor = useCallback((value: HSLColor) => {
151+
setColor(value);
152+
const hex = Colors.getHexString(value);
154153
setText(_.toUpper(getColorValue(hex)));
155154
setValid(true);
156155
}, []);
@@ -191,7 +190,7 @@ const ColorPickerDialog = (props: Props) => {
191190

192191
ColorPickerDialog.displayName = 'ColorPicker';
193192

194-
export default asBaseComponent<Props>(ColorPickerDialog);
193+
export default asBaseComponent<ColorPickerDialogProps>(ColorPickerDialog);
195194

196195
const styles = StyleSheet.create({
197196
dialog: {

src/components/colorPicker/ColorPickerDialogSliders.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import {StyleSheet} from 'react-native';
3-
43
import {Colors} from '../../style';
54
import ColorSliderGroup from '../slider/ColorSliderGroup';
65
import {HSLColor} from './ColorPickerPresenter';
@@ -9,14 +8,15 @@ import {ColorPickerDialogProps} from './ColorPickerDialog';
98
type SlidersProps = Pick<ColorPickerDialogProps, 'migrate'> & {
109
keyboardHeight: number;
1110
color: HSLColor;
12-
onSliderValueChange: (value: string) => void;
11+
onSliderValueChange: (value: HSLColor) => void;
1312
};
1413

1514
const Sliders = (props: SlidersProps) => {
1615
const {keyboardHeight, color, migrate, onSliderValueChange} = props;
17-
const colorValue = color.a === 0 ? Colors.$backgroundInverted : Colors.getHexString(color);
16+
const colorValue = color.a === 0 ? Colors.getHSL(Colors.$backgroundInverted) : color;
17+
1818
return (
19-
<ColorSliderGroup
19+
<ColorSliderGroup<HSLColor>
2020
initialColor={colorValue}
2121
containerStyle={[styles.sliderGroup, {height: keyboardHeight}]}
2222
sliderContainerStyle={styles.slider}

src/components/slider/ColorSlider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
22
import Text from '../text';
3-
import {GradientSliderTypes, ColorSliderGroupProps} from './types';
3+
import {GradientSliderTypes, ColorSliderGroupProps, HSLA} from './types';
44
import GradientSlider from './GradientSlider';
55

66
type ColorSliderProps = Pick<
7-
ColorSliderGroupProps,
7+
ColorSliderGroupProps<HSLA>,
88
'sliderContainerStyle' | 'showLabels' | 'labelsStyle' | 'accessible' | 'labels' | 'migrate' | 'initialColor'
99
> & {
1010
type: GradientSliderTypes;
Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,42 @@
1-
import React, {useState, useEffect, useCallback} from 'react';
2-
import {asBaseComponent} from '../../commons/new';
1+
import _ from 'lodash';
2+
import React, {useState, useEffect, useCallback, useMemo} from 'react';
3+
import {Colors} from '../../style';
4+
import {useThemeProps} from '../../hooks';
35
import GradientSlider from './GradientSlider';
46
import SliderGroup from './context/SliderGroup';
57
import ColorSlider from './ColorSlider';
6-
import {ColorSliderGroupProps} from './types';
8+
import {ColorSliderGroupProps, HSLA} from './types';
79

810
/**
911
* @description: A Gradient Slider component
1012
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/SliderScreen.tsx
1113
* @gif: https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/ColorSliderGroup/ColorSliderGroup.gif?raw=true
1214
*/
13-
const ColorSliderGroup = (props: ColorSliderGroupProps) => {
14-
const {initialColor, containerStyle, ...others} = props;
15-
const [color, setColor] = useState(initialColor);
16-
useEffect(() => {
17-
setColor(initialColor);
15+
const ColorSliderGroup = <T extends string | HSLA = string>(props: ColorSliderGroupProps<T>) => {
16+
const themeProps = useThemeProps(props, 'ColorSliderGroup');
17+
const {initialColor, containerStyle, onValueChange, ...others} = themeProps;
18+
const _initialColor = useMemo(() => {
19+
return _.isString(initialColor) ? Colors.HSLA(initialColor) : initialColor;
1820
}, [initialColor]);
21+
const [color, setColor] = useState<HSLA>(_initialColor);
22+
23+
useEffect(() => {
24+
setColor(_initialColor);
25+
}, [_initialColor]);
1926

20-
const onValueChange = useCallback((value: string) => {
21-
props?.onValueChange?.(value);
22-
},
23-
[props]);
27+
const _onValueChange = useCallback((value: HSLA) => {
28+
const _value = _.isString(initialColor) ? Colors.getHexString(value) : value;
29+
onValueChange?.(_value as T);
30+
}, [onValueChange, initialColor]);
2431

2532
return (
26-
<SliderGroup style={containerStyle} color={color} onValueChange={onValueChange}>
27-
<ColorSlider type={GradientSlider.types.HUE} initialColor={initialColor} {...others}/>
28-
<ColorSlider type={GradientSlider.types.SATURATION} initialColor={initialColor} {...others}/>
29-
<ColorSlider type={GradientSlider.types.LIGHTNESS} initialColor={initialColor} {...others}/>
33+
<SliderGroup style={containerStyle} color={color} onValueChange={_onValueChange}>
34+
<ColorSlider type={GradientSlider.types.HUE} initialColor={_initialColor} {...others}/>
35+
<ColorSlider type={GradientSlider.types.SATURATION} initialColor={_initialColor} {...others}/>
36+
<ColorSlider type={GradientSlider.types.LIGHTNESS} initialColor={_initialColor} {...others}/>
3037
</SliderGroup>
3138
);
3239
};
3340

3441
ColorSliderGroup.displayName = 'ColorSliderGroup';
35-
export default asBaseComponent<ColorSliderGroupProps, typeof ColorSliderGroup>(ColorSliderGroup);
42+
export default ColorSliderGroup;

src/components/slider/GradientSlider.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
import _ from 'lodash';
2-
import tinycolor from 'tinycolor2';
3-
import React, {useCallback, useEffect, useState, useRef, useMemo} from 'react';
2+
import React, {useCallback, useEffect, useState, useMemo} from 'react';
43
import {asBaseComponent, forwardRef, ForwardRefInjectedProps} from '../../commons/new';
54
import {ComponentStatics} from '../../typings/common';
65
import {Colors} from '../../style';
76
import {Slider as NewSlider} from '../../incubator';
87
import Gradient from '../gradient';
9-
import {GradientSliderProps, GradientSliderTypes} from './types';
8+
import {GradientSliderProps, GradientSliderTypes, HSLA} from './types';
109
import Slider from './index';
1110
import {SliderContextProps} from './context/SliderContext';
1211
import asSliderGroupChild from './context/asSliderGroupChild';
1312

14-
type GradientSliderComponentProps = {
13+
type GradientSliderComponentProps<T> = {
1514
sliderContext: SliderContextProps;
16-
} & GradientSliderProps;
15+
} & GradientSliderProps<T>;
1716

18-
type Props = GradientSliderComponentProps & ForwardRefInjectedProps;
17+
type Props<T> = GradientSliderComponentProps<T> & ForwardRefInjectedProps;
1918

2019
/**
2120
* @description: A Gradient Slider component
2221
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/SliderScreen.tsx
2322
* @gif: https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/GradientSlider/GradientSlider.gif?raw=true
2423
*/
25-
const GradientSlider = (props: Props) => {
24+
const GradientSlider = <T extends string | HSLA = string>(props: Props<T>) => {
2625
const {
2726
type = GradientSliderTypes.DEFAULT,
2827
gradientSteps = 120,
@@ -37,12 +36,14 @@ const GradientSlider = (props: Props) => {
3736
...others
3837
} = props;
3938

40-
const initialColor = useRef(Colors.getHSL(propsColors));
41-
const [color, setColor] = useState(Colors.getHSL(propsColors));
39+
const initialColor = useMemo<HSLA>(() => {
40+
return _.isString(propsColors) ? Colors.HSLA(propsColors) : propsColors;
41+
}, [propsColors]);
42+
const [color, setColor] = useState(initialColor);
4243

4344
useEffect(() => {
44-
setColor(Colors.getHSL(propsColors));
45-
}, [propsColors]);
45+
setColor(initialColor);
46+
}, [initialColor]);
4647

4748
const getColor = useCallback(() => {
4849
return color || sliderContext.value;
@@ -80,7 +81,7 @@ const GradientSlider = (props: Props) => {
8081
},
8182
[_onValueChange]);
8283

83-
const updateColor = useCallback((color: tinycolor.ColorFormats.HSLA) => {
84+
const updateColor = useCallback((color: HSLA) => {
8485
if (!_.isEmpty(sliderContext)) {
8586
sliderContext.setValue?.(color);
8687
} else {
@@ -92,7 +93,7 @@ const GradientSlider = (props: Props) => {
9293
[sliderContext, onValueChange]);
9394

9495
const reset = useCallback(() => {
95-
updateColor(initialColor.current);
96+
updateColor(initialColor);
9697
}, [initialColor, updateColor]);
9798

9899
const updateAlpha = useCallback((a: number) => {
@@ -129,17 +130,17 @@ const GradientSlider = (props: Props) => {
129130
case GradientSliderTypes.HUE:
130131
step = 1;
131132
maximumValue = 359;
132-
value = initialColor.current.h;
133+
value = initialColor.h;
133134
renderTrack = renderHueGradient;
134135
sliderOnValueChange = updateHue;
135136
break;
136137
case GradientSliderTypes.LIGHTNESS:
137-
value = initialColor.current.l;
138+
value = initialColor.l;
138139
renderTrack = renderLightnessGradient;
139140
sliderOnValueChange = updateLightness;
140141
break;
141142
case GradientSliderTypes.SATURATION:
142-
value = initialColor.current.s;
143+
value = initialColor.s;
143144
renderTrack = renderSaturationGradient;
144145
sliderOnValueChange = updateSaturation;
145146
break;
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React from 'react';
2+
import {HSLA} from '../types';
23

34
export interface SliderContextProps {
4-
value?: tinycolor.ColorFormats.HSLA;
5-
setValue?: (value: tinycolor.ColorFormats.HSLA) => void;
5+
value?: HSLA;
6+
setValue?: (value: HSLA) => void;
67
}
78

89
const SliderContext: React.Context<SliderContextProps> = React.createContext({});
10+
SliderContext.displayName = 'IGNORE';
911
export default SliderContext;

src/components/slider/context/SliderGroup.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
import tinycolor from 'tinycolor2';
21
import React, {useCallback, useMemo, useState} from 'react';
32
import {StyleProp, ViewStyle} from 'react-native';
4-
import {Colors} from '../../../style';
53
import View from '../../view';
4+
import {HSLA} from '../types';
65
import SliderContext from './SliderContext';
76

87
interface SliderGroupProps {
9-
color: string;
10-
onValueChange: (color: string) => void;
8+
color: HSLA;
9+
onValueChange: (value: HSLA) => void;
1110
style?: StyleProp<ViewStyle>;
1211
children?: React.ReactNode;
1312
}
1413

1514
const SliderGroup = (props: SliderGroupProps) => {
1615
const {color, onValueChange, children} = props;
17-
const [value, setValue] = useState(Colors.getHSL(color));
16+
const [value, setValue] = useState(color);
1817

19-
const _setValue = useCallback((value: tinycolor.ColorFormats.HSLA) => {
18+
const _setValue = useCallback((value: HSLA) => {
2019
setValue(value);
21-
onValueChange?.(Colors.getHexString(value));
20+
onValueChange?.(value);
2221
},
2322
[onValueChange]);
2423

src/components/slider/types.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import tinycolor from 'tinycolor2';
12
import {ReactElement} from 'react';
23
import {StyleProp, ViewStyle, TextStyle} from 'react-native';
34
import {ThumbProps} from './Thumb';
45

6+
export type HSLA = tinycolor.ColorFormats.HSLA;
7+
58
export type SliderOnValueChange = (value: number) => void;
69
export type SliderOnRangeChange = (values: {min: number; max: number}) => void;
710

@@ -107,11 +110,11 @@ export enum GradientSliderTypes {
107110
SATURATION = 'saturation'
108111
}
109112

110-
export type GradientSliderProps = Omit<SliderProps, 'onValueChange'> & {
113+
export type GradientSliderProps<T> = Omit<SliderProps, 'onValueChange'> & {
111114
/**
112115
* The gradient color
113116
*/
114-
color?: string;
117+
color?: T;
115118
/**
116119
* The gradient type (default, hue, lightness, saturation)
117120
*/
@@ -138,15 +141,15 @@ export type GradientSliderProps = Omit<SliderProps, 'onValueChange'> & {
138141
disabled?: boolean;
139142
}
140143

141-
export type ColorSliderGroupProps = {
144+
export type ColorSliderGroupProps<T> = {
142145
/**
143146
* The gradient color
144147
*/
145-
initialColor: string;
148+
initialColor: T;
146149
/**
147150
* Callback for onValueChange returns the new hex color
148151
*/
149-
onValueChange?: (value: string) => void;
152+
onValueChange?: (value: T) => void;
150153
/**
151154
* Group container style
152155
*/

0 commit comments

Comments
 (0)