react-native-color-picker-palette 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +340 -0
- package/package.json +70 -0
- package/src/core/hooks/index.ts +2 -0
- package/src/core/hooks/useColor.ts +93 -0
- package/src/core/hooks/useComponentLayout.ts +38 -0
- package/src/core/index.ts +19 -0
- package/src/core/services/ColorService.ts +338 -0
- package/src/core/services/index.ts +1 -0
- package/src/core/types/index.ts +211 -0
- package/src/core/utils/clamp.ts +16 -0
- package/src/core/utils/format.ts +59 -0
- package/src/core/utils/index.ts +8 -0
- package/src/full/components/Alpha.tsx +221 -0
- package/src/full/components/ColorPicker.tsx +206 -0
- package/src/full/components/Fields/HexField.tsx +125 -0
- package/src/full/components/Fields/RgbFields.tsx +192 -0
- package/src/full/components/Fields/index.tsx +70 -0
- package/src/full/components/Hue.tsx +188 -0
- package/src/full/components/RectangleSaturation.tsx +203 -0
- package/src/full/components/Saturation.tsx +258 -0
- package/src/full/components/Thumb.tsx +47 -0
- package/src/full/components/Value.tsx +192 -0
- package/src/full/components/index.ts +8 -0
- package/src/full/index.ts +69 -0
- package/src/index.ts +19 -0
- package/src/lite/components/Alpha.tsx +228 -0
- package/src/lite/components/ColorPicker.tsx +209 -0
- package/src/lite/components/Fields/HexField.tsx +103 -0
- package/src/lite/components/Fields/RgbFields.tsx +138 -0
- package/src/lite/components/Fields/index.tsx +53 -0
- package/src/lite/components/Hue.tsx +192 -0
- package/src/lite/components/RectangleSaturation.tsx +238 -0
- package/src/lite/components/Saturation.tsx +289 -0
- package/src/lite/components/Thumb.tsx +47 -0
- package/src/lite/components/Value.tsx +201 -0
- package/src/lite/components/index.ts +8 -0
- package/src/lite/index.ts +75 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import type { IFieldsProps } from '../../../core/types';
|
|
4
|
+
import { HexField } from './HexField';
|
|
5
|
+
import { RgbFields } from './RgbFields';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Color input fields container
|
|
9
|
+
*/
|
|
10
|
+
export const Fields = memo(
|
|
11
|
+
({
|
|
12
|
+
color,
|
|
13
|
+
onChange,
|
|
14
|
+
onChangeComplete,
|
|
15
|
+
disabled = false,
|
|
16
|
+
}: IFieldsProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<View style={styles.container}>
|
|
19
|
+
<View style={styles.hexContainer}>
|
|
20
|
+
<HexField
|
|
21
|
+
color={color}
|
|
22
|
+
onChange={onChange}
|
|
23
|
+
onChangeComplete={onChangeComplete}
|
|
24
|
+
disabled={disabled}
|
|
25
|
+
/>
|
|
26
|
+
</View>
|
|
27
|
+
<View style={styles.rgbContainer}>
|
|
28
|
+
<RgbFields
|
|
29
|
+
color={color}
|
|
30
|
+
onChange={onChange}
|
|
31
|
+
onChangeComplete={onChangeComplete}
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
/>
|
|
34
|
+
</View>
|
|
35
|
+
</View>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const styles = StyleSheet.create({
|
|
41
|
+
container: {
|
|
42
|
+
flexDirection: 'row',
|
|
43
|
+
gap: 12,
|
|
44
|
+
alignItems: 'flex-end',
|
|
45
|
+
},
|
|
46
|
+
hexContainer: { flex: 1 },
|
|
47
|
+
rgbContainer: { flex: 2 },
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
Fields.displayName = 'Fields';
|
|
51
|
+
|
|
52
|
+
export { HexField } from './HexField';
|
|
53
|
+
export { RgbFields } from './RgbFields';
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
PanResponder,
|
|
6
|
+
GestureResponderEvent,
|
|
7
|
+
LayoutChangeEvent,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import type { IHueProps } from '../../core/types';
|
|
10
|
+
import { ColorService } from '../../core/services';
|
|
11
|
+
import { clamp } from '../../core/utils';
|
|
12
|
+
import { Thumb } from './Thumb';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hue slider bar component - Zero Dependencies Version
|
|
16
|
+
*
|
|
17
|
+
* Uses pure React Native Views to create the rainbow gradient.
|
|
18
|
+
* No react-native-svg required.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <Hue
|
|
23
|
+
* color={color}
|
|
24
|
+
* onChange={handleChange}
|
|
25
|
+
* barHeight={10}
|
|
26
|
+
* thumbSize={24}
|
|
27
|
+
* />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const Hue = memo(
|
|
31
|
+
({
|
|
32
|
+
color,
|
|
33
|
+
onChange,
|
|
34
|
+
onChangeComplete,
|
|
35
|
+
barHeight,
|
|
36
|
+
thumbSize,
|
|
37
|
+
disabled = false,
|
|
38
|
+
}: IHueProps) => {
|
|
39
|
+
const containerRef = useRef<View>(null);
|
|
40
|
+
const [width, setWidth] = useState(1);
|
|
41
|
+
const measurementCache = useRef<number | null>(null);
|
|
42
|
+
|
|
43
|
+
// Calculate thumb position from hue value
|
|
44
|
+
const thumbPosition = useMemo(() => {
|
|
45
|
+
return (color.hsv.h / 360) * width;
|
|
46
|
+
}, [color.hsv.h, width]);
|
|
47
|
+
|
|
48
|
+
// Update measurement cache
|
|
49
|
+
const updateMeasurement = useCallback(() => {
|
|
50
|
+
return new Promise<number>((resolve) => {
|
|
51
|
+
if (measurementCache.current !== null) {
|
|
52
|
+
resolve(measurementCache.current);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
containerRef.current?.measureInWindow((x) => {
|
|
56
|
+
measurementCache.current = x;
|
|
57
|
+
resolve(x);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
// Convert touch position to hue
|
|
63
|
+
const updateColorFromPosition = useCallback(
|
|
64
|
+
async (pageX: number, isFinal: boolean) => {
|
|
65
|
+
const wx = await updateMeasurement();
|
|
66
|
+
const x = clamp(pageX - wx, 0, width);
|
|
67
|
+
const hue = (x / width) * 360;
|
|
68
|
+
|
|
69
|
+
const nextColor = ColorService.convert('hsv', {
|
|
70
|
+
...color.hsv,
|
|
71
|
+
h: clamp(hue, 0, 360),
|
|
72
|
+
s: 100,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
onChange(nextColor);
|
|
76
|
+
|
|
77
|
+
if (isFinal) {
|
|
78
|
+
onChangeComplete?.(nextColor);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[color.hsv, width, onChange, onChangeComplete, updateMeasurement]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// PanResponder for touch handling
|
|
85
|
+
const panResponder = useMemo(
|
|
86
|
+
() =>
|
|
87
|
+
PanResponder.create({
|
|
88
|
+
onStartShouldSetPanResponder: () => !disabled,
|
|
89
|
+
onMoveShouldSetPanResponder: () => !disabled,
|
|
90
|
+
onPanResponderGrant: (evt: GestureResponderEvent) => {
|
|
91
|
+
measurementCache.current = null;
|
|
92
|
+
updateColorFromPosition(evt.nativeEvent.pageX, false);
|
|
93
|
+
},
|
|
94
|
+
onPanResponderMove: (evt: GestureResponderEvent) => {
|
|
95
|
+
updateColorFromPosition(evt.nativeEvent.pageX, false);
|
|
96
|
+
},
|
|
97
|
+
onPanResponderRelease: (evt: GestureResponderEvent) => {
|
|
98
|
+
updateColorFromPosition(evt.nativeEvent.pageX, true);
|
|
99
|
+
},
|
|
100
|
+
}),
|
|
101
|
+
[disabled, updateColorFromPosition]
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Handle layout to get width and clear cache
|
|
105
|
+
const handleLayout = useCallback((event: LayoutChangeEvent) => {
|
|
106
|
+
setWidth(event.nativeEvent.layout.width);
|
|
107
|
+
measurementCache.current = null;
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
// Generate rainbow gradient using colored Views (1 pixel per segment)
|
|
111
|
+
const hueSegments = useMemo(() => {
|
|
112
|
+
const segments: JSX.Element[] = [];
|
|
113
|
+
const steps = Math.max(1, Math.round(width));
|
|
114
|
+
|
|
115
|
+
for (let i = 0; i < steps; i++) {
|
|
116
|
+
const hue = (i / steps) * 360;
|
|
117
|
+
|
|
118
|
+
segments.push(
|
|
119
|
+
<View
|
|
120
|
+
key={i}
|
|
121
|
+
style={[
|
|
122
|
+
styles.segment,
|
|
123
|
+
{
|
|
124
|
+
flex: 1,
|
|
125
|
+
backgroundColor: `hsl(${hue}, 100%, 50%)`,
|
|
126
|
+
},
|
|
127
|
+
]}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return segments;
|
|
133
|
+
}, [width]);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<View
|
|
137
|
+
ref={containerRef}
|
|
138
|
+
style={[
|
|
139
|
+
styles.container,
|
|
140
|
+
{
|
|
141
|
+
height: barHeight + thumbSize,
|
|
142
|
+
opacity: disabled ? 0.5 : 1,
|
|
143
|
+
},
|
|
144
|
+
]}
|
|
145
|
+
onLayout={handleLayout}
|
|
146
|
+
{...panResponder.panHandlers}
|
|
147
|
+
>
|
|
148
|
+
{/* Gradient bar using colored Views */}
|
|
149
|
+
<View style={[styles.barContainer, { height: barHeight, top: thumbSize / 2, borderRadius: barHeight / 2 }]}>
|
|
150
|
+
{hueSegments}
|
|
151
|
+
</View>
|
|
152
|
+
|
|
153
|
+
{/* Thumb indicator - centered vertically with bar */}
|
|
154
|
+
<View
|
|
155
|
+
style={[
|
|
156
|
+
styles.thumbContainer,
|
|
157
|
+
{
|
|
158
|
+
left: thumbPosition - thumbSize / 2,
|
|
159
|
+
top: barHeight / 2,
|
|
160
|
+
},
|
|
161
|
+
]}
|
|
162
|
+
pointerEvents="none"
|
|
163
|
+
>
|
|
164
|
+
<Thumb size={thumbSize} color={`hsl(${color.hsv.h}, 100%, 50%)`} />
|
|
165
|
+
</View>
|
|
166
|
+
</View>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const styles = StyleSheet.create({
|
|
172
|
+
container: {
|
|
173
|
+
position: 'relative',
|
|
174
|
+
width: '100%',
|
|
175
|
+
},
|
|
176
|
+
barContainer: {
|
|
177
|
+
position: 'absolute',
|
|
178
|
+
left: 0,
|
|
179
|
+
right: 0,
|
|
180
|
+
flexDirection: 'row',
|
|
181
|
+
overflow: 'hidden',
|
|
182
|
+
},
|
|
183
|
+
segment: {
|
|
184
|
+
height: '100%',
|
|
185
|
+
},
|
|
186
|
+
thumbContainer: {
|
|
187
|
+
position: 'absolute',
|
|
188
|
+
zIndex: 10,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
Hue.displayName = 'Hue';
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
PanResponder,
|
|
6
|
+
GestureResponderEvent,
|
|
7
|
+
LayoutChangeEvent,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import type { IRectangleSaturationProps } from '../../core/types';
|
|
10
|
+
import { ColorService } from '../../core/services';
|
|
11
|
+
import { clamp } from '../../core/utils';
|
|
12
|
+
import { Thumb } from './Thumb';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Rectangle Saturation/Value Picker - Zero Dependencies Version
|
|
16
|
+
*
|
|
17
|
+
* Uses pure React Native Views for gradients.
|
|
18
|
+
* No react-native-svg required.
|
|
19
|
+
*
|
|
20
|
+
* Layout:
|
|
21
|
+
* - Top-right: Current hue at full saturation (100% S, 100% V)
|
|
22
|
+
* - Top-left: White (0% S, 100% V)
|
|
23
|
+
* - Bottom-left: Black (0% S, 0% V)
|
|
24
|
+
* - Bottom-right: Black (100% S, 0% V)
|
|
25
|
+
*
|
|
26
|
+
* X-axis: Saturation (0% to 100%)
|
|
27
|
+
* Y-axis: Value/Brightness (100% to 0%)
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <RectangleSaturation
|
|
32
|
+
* color={color}
|
|
33
|
+
* onChange={handleChange}
|
|
34
|
+
* width={250}
|
|
35
|
+
* height={150}
|
|
36
|
+
* thumbSize={24}
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export const RectangleSaturation = memo(
|
|
41
|
+
({
|
|
42
|
+
color,
|
|
43
|
+
onChange,
|
|
44
|
+
onChangeComplete,
|
|
45
|
+
width,
|
|
46
|
+
height,
|
|
47
|
+
thumbSize,
|
|
48
|
+
disabled = false,
|
|
49
|
+
}: IRectangleSaturationProps) => {
|
|
50
|
+
// Key: steps = dimension (1 pixel per segment) avoids all sub-pixel gaps
|
|
51
|
+
const horizontalSteps = width;
|
|
52
|
+
const verticalSteps = height;
|
|
53
|
+
const containerRef = useRef<View>(null);
|
|
54
|
+
const measurementCache = useRef<{ x: number; y: number } | null>(null);
|
|
55
|
+
const [isLayoutReady, setIsLayoutReady] = useState(false);
|
|
56
|
+
|
|
57
|
+
// Calculate thumb position from HSV values
|
|
58
|
+
const thumbPosition = useMemo(() => {
|
|
59
|
+
const x = (color.hsv.s / 100) * width - thumbSize / 2;
|
|
60
|
+
const y = ((100 - color.hsv.v) / 100) * height - thumbSize / 2;
|
|
61
|
+
return { x: clamp(x, -thumbSize / 2, width - thumbSize / 2), y: clamp(y, -thumbSize / 2, height - thumbSize / 2) };
|
|
62
|
+
}, [color.hsv.s, color.hsv.v, width, height, thumbSize]);
|
|
63
|
+
|
|
64
|
+
// Update measurement cache
|
|
65
|
+
const updateMeasurement = useCallback(() => {
|
|
66
|
+
return new Promise<{ x: number; y: number }>((resolve) => {
|
|
67
|
+
if (measurementCache.current) {
|
|
68
|
+
resolve(measurementCache.current);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
containerRef.current?.measureInWindow((x, y) => {
|
|
72
|
+
measurementCache.current = { x, y };
|
|
73
|
+
resolve({ x, y });
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
// Convert touch coordinates to HSV
|
|
79
|
+
const updateColorFromPosition = useCallback(
|
|
80
|
+
async (pageX: number, pageY: number, isFinal: boolean) => {
|
|
81
|
+
const measurement = await updateMeasurement();
|
|
82
|
+
|
|
83
|
+
const x = clamp(pageX - measurement.x, 0, width);
|
|
84
|
+
const y = clamp(pageY - measurement.y, 0, height);
|
|
85
|
+
|
|
86
|
+
const saturation = (x / width) * 100;
|
|
87
|
+
const value = 100 - (y / height) * 100;
|
|
88
|
+
|
|
89
|
+
const nextColor = ColorService.convert('hsv', {
|
|
90
|
+
h: color.hsv.h,
|
|
91
|
+
s: clamp(saturation, 0, 100),
|
|
92
|
+
v: clamp(value, 0, 100),
|
|
93
|
+
a: color.hsv.a,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
onChange(nextColor);
|
|
97
|
+
|
|
98
|
+
if (isFinal) {
|
|
99
|
+
onChangeComplete?.(nextColor);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
[color.hsv.h, color.hsv.a, width, height, onChange, onChangeComplete, updateMeasurement]
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Handle layout
|
|
106
|
+
const handleLayout = useCallback((event: LayoutChangeEvent) => {
|
|
107
|
+
measurementCache.current = null;
|
|
108
|
+
setIsLayoutReady(true);
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
// PanResponder
|
|
112
|
+
const panResponder = useMemo(
|
|
113
|
+
() =>
|
|
114
|
+
PanResponder.create({
|
|
115
|
+
onStartShouldSetPanResponder: () => !disabled,
|
|
116
|
+
onMoveShouldSetPanResponder: () => !disabled,
|
|
117
|
+
onPanResponderGrant: (evt: GestureResponderEvent) => {
|
|
118
|
+
measurementCache.current = null;
|
|
119
|
+
updateColorFromPosition(evt.nativeEvent.pageX, evt.nativeEvent.pageY, false);
|
|
120
|
+
},
|
|
121
|
+
onPanResponderMove: (evt: GestureResponderEvent) => {
|
|
122
|
+
updateColorFromPosition(evt.nativeEvent.pageX, evt.nativeEvent.pageY, false);
|
|
123
|
+
},
|
|
124
|
+
onPanResponderRelease: (evt: GestureResponderEvent) => {
|
|
125
|
+
updateColorFromPosition(evt.nativeEvent.pageX, evt.nativeEvent.pageY, true);
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
[disabled, updateColorFromPosition]
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// Generate white gradient overlay (left to right: white to transparent)
|
|
132
|
+
const whiteGradient = useMemo(() => {
|
|
133
|
+
const segments: JSX.Element[] = [];
|
|
134
|
+
for (let i = 0; i < horizontalSteps; i++) {
|
|
135
|
+
const opacity = 1 - i / horizontalSteps;
|
|
136
|
+
segments.push(
|
|
137
|
+
<View
|
|
138
|
+
key={`white-${i}`}
|
|
139
|
+
style={{
|
|
140
|
+
flex: 1,
|
|
141
|
+
backgroundColor: `rgba(255, 255, 255, ${opacity})`,
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return segments;
|
|
147
|
+
}, [horizontalSteps]);
|
|
148
|
+
|
|
149
|
+
// Generate black gradient overlay (top to bottom: transparent to black)
|
|
150
|
+
const blackGradient = useMemo(() => {
|
|
151
|
+
const segments: JSX.Element[] = [];
|
|
152
|
+
for (let i = 0; i < verticalSteps; i++) {
|
|
153
|
+
const opacity = i / verticalSteps;
|
|
154
|
+
segments.push(
|
|
155
|
+
<View
|
|
156
|
+
key={`black-${i}`}
|
|
157
|
+
style={{
|
|
158
|
+
flex: 1,
|
|
159
|
+
backgroundColor: `rgba(0, 0, 0, ${opacity})`,
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return segments;
|
|
165
|
+
}, [verticalSteps]);
|
|
166
|
+
|
|
167
|
+
// Current hue color at full saturation
|
|
168
|
+
const hueColor = `hsl(${color.hsv.h}, 100%, 50%)`;
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<View
|
|
172
|
+
ref={containerRef}
|
|
173
|
+
onLayout={handleLayout}
|
|
174
|
+
style={[
|
|
175
|
+
styles.container,
|
|
176
|
+
{
|
|
177
|
+
width,
|
|
178
|
+
height,
|
|
179
|
+
opacity: disabled ? 0.5 : 1,
|
|
180
|
+
},
|
|
181
|
+
]}
|
|
182
|
+
{...panResponder.panHandlers}
|
|
183
|
+
>
|
|
184
|
+
{/* Base hue color */}
|
|
185
|
+
<View style={[styles.hueLayer, { backgroundColor: hueColor }]} />
|
|
186
|
+
|
|
187
|
+
{/* White gradient (horizontal: left white to right transparent) */}
|
|
188
|
+
<View style={styles.whiteGradientContainer}>
|
|
189
|
+
{whiteGradient}
|
|
190
|
+
</View>
|
|
191
|
+
|
|
192
|
+
{/* Black gradient (vertical: top transparent to bottom black) */}
|
|
193
|
+
<View style={styles.blackGradientContainer}>
|
|
194
|
+
{blackGradient}
|
|
195
|
+
</View>
|
|
196
|
+
|
|
197
|
+
{/* Thumb */}
|
|
198
|
+
<View
|
|
199
|
+
style={[
|
|
200
|
+
styles.thumbContainer,
|
|
201
|
+
{
|
|
202
|
+
left: thumbPosition.x,
|
|
203
|
+
top: thumbPosition.y,
|
|
204
|
+
},
|
|
205
|
+
]}
|
|
206
|
+
pointerEvents="none"
|
|
207
|
+
>
|
|
208
|
+
<Thumb size={thumbSize} color={color.hex} />
|
|
209
|
+
</View>
|
|
210
|
+
</View>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const styles = StyleSheet.create({
|
|
216
|
+
container: {
|
|
217
|
+
position: 'relative',
|
|
218
|
+
borderRadius: 8,
|
|
219
|
+
overflow: 'hidden',
|
|
220
|
+
},
|
|
221
|
+
hueLayer: {
|
|
222
|
+
...StyleSheet.absoluteFillObject,
|
|
223
|
+
},
|
|
224
|
+
whiteGradientContainer: {
|
|
225
|
+
...StyleSheet.absoluteFillObject,
|
|
226
|
+
flexDirection: 'row',
|
|
227
|
+
},
|
|
228
|
+
blackGradientContainer: {
|
|
229
|
+
...StyleSheet.absoluteFillObject,
|
|
230
|
+
flexDirection: 'column',
|
|
231
|
+
},
|
|
232
|
+
thumbContainer: {
|
|
233
|
+
position: 'absolute',
|
|
234
|
+
zIndex: 10,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
RectangleSaturation.displayName = 'RectangleSaturation';
|