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.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/package.json +70 -0
  4. package/src/core/hooks/index.ts +2 -0
  5. package/src/core/hooks/useColor.ts +93 -0
  6. package/src/core/hooks/useComponentLayout.ts +38 -0
  7. package/src/core/index.ts +19 -0
  8. package/src/core/services/ColorService.ts +338 -0
  9. package/src/core/services/index.ts +1 -0
  10. package/src/core/types/index.ts +211 -0
  11. package/src/core/utils/clamp.ts +16 -0
  12. package/src/core/utils/format.ts +59 -0
  13. package/src/core/utils/index.ts +8 -0
  14. package/src/full/components/Alpha.tsx +221 -0
  15. package/src/full/components/ColorPicker.tsx +206 -0
  16. package/src/full/components/Fields/HexField.tsx +125 -0
  17. package/src/full/components/Fields/RgbFields.tsx +192 -0
  18. package/src/full/components/Fields/index.tsx +70 -0
  19. package/src/full/components/Hue.tsx +188 -0
  20. package/src/full/components/RectangleSaturation.tsx +203 -0
  21. package/src/full/components/Saturation.tsx +258 -0
  22. package/src/full/components/Thumb.tsx +47 -0
  23. package/src/full/components/Value.tsx +192 -0
  24. package/src/full/components/index.ts +8 -0
  25. package/src/full/index.ts +69 -0
  26. package/src/index.ts +19 -0
  27. package/src/lite/components/Alpha.tsx +228 -0
  28. package/src/lite/components/ColorPicker.tsx +209 -0
  29. package/src/lite/components/Fields/HexField.tsx +103 -0
  30. package/src/lite/components/Fields/RgbFields.tsx +138 -0
  31. package/src/lite/components/Fields/index.tsx +53 -0
  32. package/src/lite/components/Hue.tsx +192 -0
  33. package/src/lite/components/RectangleSaturation.tsx +238 -0
  34. package/src/lite/components/Saturation.tsx +289 -0
  35. package/src/lite/components/Thumb.tsx +47 -0
  36. package/src/lite/components/Value.tsx +201 -0
  37. package/src/lite/components/index.ts +8 -0
  38. package/src/lite/index.ts +75 -0
@@ -0,0 +1,228 @@
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 { IAlphaProps } from '../../core/types';
10
+ import { ColorService } from '../../core/services';
11
+ import { clamp } from '../../core/utils';
12
+ import { Thumb } from './Thumb';
13
+
14
+ /**
15
+ * Alpha (transparency) slider bar component - Zero Dependencies Version
16
+ *
17
+ * Uses pure React Native Views for checkerboard and gradient.
18
+ * No react-native-svg required.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <Alpha
23
+ * color={color}
24
+ * onChange={handleChange}
25
+ * barHeight={10}
26
+ * thumbSize={24}
27
+ * />
28
+ * ```
29
+ */
30
+ export const Alpha = memo(
31
+ ({
32
+ color,
33
+ onChange,
34
+ onChangeComplete,
35
+ barHeight,
36
+ thumbSize,
37
+ disabled = false,
38
+ }: IAlphaProps) => {
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 alpha value (a=1 should be at right)
44
+ const thumbPosition = useMemo(() => {
45
+ return color.hsv.a * width;
46
+ }, [color.hsv.a, 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 alpha
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 alpha = x / width;
68
+
69
+ const nextColor = ColorService.convert('hsv', {
70
+ ...color.hsv,
71
+ a: clamp(alpha, 0, 1),
72
+ });
73
+
74
+ onChange(nextColor);
75
+
76
+ if (isFinal) {
77
+ onChangeComplete?.(nextColor);
78
+ }
79
+ },
80
+ [color.hsv, width, onChange, onChangeComplete, updateMeasurement]
81
+ );
82
+
83
+ // PanResponder for touch handling
84
+ const panResponder = useMemo(
85
+ () =>
86
+ PanResponder.create({
87
+ onStartShouldSetPanResponder: () => !disabled,
88
+ onMoveShouldSetPanResponder: () => !disabled,
89
+ onPanResponderGrant: (evt: GestureResponderEvent) => {
90
+ measurementCache.current = null;
91
+ updateColorFromPosition(evt.nativeEvent.pageX, false);
92
+ },
93
+ onPanResponderMove: (evt: GestureResponderEvent) => {
94
+ updateColorFromPosition(evt.nativeEvent.pageX, false);
95
+ },
96
+ onPanResponderRelease: (evt: GestureResponderEvent) => {
97
+ updateColorFromPosition(evt.nativeEvent.pageX, true);
98
+ },
99
+ }),
100
+ [disabled, updateColorFromPosition]
101
+ );
102
+
103
+ // Handle layout to get width and clear cache
104
+ const handleLayout = useCallback((event: LayoutChangeEvent) => {
105
+ setWidth(event.nativeEvent.layout.width);
106
+ measurementCache.current = null;
107
+ }, []);
108
+
109
+ // Generate alpha gradient using colored Views with varying opacity
110
+ const alphaGradientSegments = useMemo(() => {
111
+ const segments: JSX.Element[] = [];
112
+ const steps = Math.max(1, Math.round(width));
113
+ const { r, g, b } = color.rgb;
114
+
115
+ for (let i = 0; i < steps; i++) {
116
+ const alpha = i / (steps - 1 || 1);
117
+
118
+ segments.push(
119
+ <View
120
+ key={i}
121
+ style={[
122
+ styles.gradientSegment,
123
+ {
124
+ flex: 1,
125
+ backgroundColor: `rgba(${r}, ${g}, ${b}, ${alpha})`,
126
+ },
127
+ ]}
128
+ />
129
+ );
130
+ }
131
+
132
+ return segments;
133
+ }, [width, color.rgb.r, color.rgb.g, color.rgb.b]);
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
+ {/* Bar with checkerboard and gradient */}
149
+ <View style={[styles.barContainer, { height: barHeight, top: thumbSize / 2 }]}>
150
+ {/* Checkerboard background */}
151
+ <View style={[styles.checkerboard, { borderRadius: barHeight / 2 }]}>
152
+ {Array.from({ length: 2 }).map((_, rowIndex) => {
153
+ const checkerSize = barHeight / 2;
154
+ const cellCount = Math.ceil(width / checkerSize) + 1;
155
+ return (
156
+ <View key={rowIndex} style={[styles.checkerRow, { height: checkerSize }]}>
157
+ {Array.from({ length: cellCount }).map((_, i) => (
158
+ <View
159
+ key={i}
160
+ style={{
161
+ width: checkerSize,
162
+ height: checkerSize,
163
+ backgroundColor: (i + rowIndex) % 2 === 0 ? '#FFFFFF' : '#CCCCCC',
164
+ }}
165
+ />
166
+ ))}
167
+ </View>
168
+ );
169
+ })}
170
+ </View>
171
+
172
+ {/* Color gradient overlay using Views */}
173
+ <View style={[styles.gradientContainer, { borderRadius: barHeight / 2 }]}>
174
+ {alphaGradientSegments}
175
+ </View>
176
+ </View>
177
+
178
+ {/* Thumb indicator */}
179
+ <View
180
+ style={[
181
+ styles.thumbContainer,
182
+ {
183
+ left: thumbPosition - thumbSize / 2,
184
+ top: barHeight / 2,
185
+ },
186
+ ]}
187
+ pointerEvents="none"
188
+ >
189
+ <Thumb size={thumbSize} color={`rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.hsv.a})`} />
190
+ </View>
191
+ </View>
192
+ );
193
+ }
194
+ );
195
+
196
+ const styles = StyleSheet.create({
197
+ container: {
198
+ position: 'relative',
199
+ width: '100%',
200
+ },
201
+ barContainer: {
202
+ position: 'absolute',
203
+ left: 0,
204
+ right: 0,
205
+ overflow: 'hidden',
206
+ },
207
+ checkerboard: {
208
+ ...StyleSheet.absoluteFillObject,
209
+ overflow: 'hidden',
210
+ },
211
+ checkerRow: {
212
+ flexDirection: 'row',
213
+ },
214
+ gradientContainer: {
215
+ ...StyleSheet.absoluteFillObject,
216
+ flexDirection: 'row',
217
+ overflow: 'hidden',
218
+ },
219
+ gradientSegment: {
220
+ height: '100%',
221
+ },
222
+ thumbContainer: {
223
+ position: 'absolute',
224
+ zIndex: 10,
225
+ },
226
+ });
227
+
228
+ Alpha.displayName = 'Alpha';
@@ -0,0 +1,209 @@
1
+ import React, { memo } from 'react';
2
+ import { View, StyleSheet } from 'react-native';
3
+ import type { IColorPickerProps } from '../../core/types';
4
+ import { Saturation } from './Saturation';
5
+ import { RectangleSaturation } from './RectangleSaturation';
6
+ import { Hue } from './Hue';
7
+ import { Alpha } from './Alpha';
8
+ import { Value } from './Value';
9
+ import { Fields } from './Fields';
10
+
11
+ /**
12
+ * Main ColorPicker component (Lite version - Zero Dependencies)
13
+ *
14
+ * This version uses pure React Native Views instead of react-native-svg.
15
+ * No additional native dependencies required.
16
+ *
17
+ * Features:
18
+ * - Circular color wheel or rectangle for saturation/value selection
19
+ * - Horizontal hue bar
20
+ * - Horizontal alpha bar with checkerboard background
21
+ * - HEX and RGB input fields
22
+ * - Circle thumbs with white 2px border showing selected color
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { ColorPicker, useColor } from 'react-native-color-palette/lite';
27
+ *
28
+ * function MyComponent() {
29
+ * const [color, setColor] = useColor('#FF0000');
30
+ *
31
+ * return (
32
+ * <ColorPicker
33
+ * color={color}
34
+ * onChange={setColor}
35
+ * variant="rectangle"
36
+ * onChangeComplete={(c) => console.log('Final color:', c.hex)}
37
+ * />
38
+ * );
39
+ * }
40
+ * ```
41
+ */
42
+ export const ColorPicker = memo(
43
+ ({
44
+ color,
45
+ onChange,
46
+ onChangeComplete,
47
+ variant = 'rectangle',
48
+ width = 250,
49
+ barHeight = 10,
50
+ thumbSize = 24,
51
+ hideHue = false,
52
+ hideAlpha = false,
53
+ hidePreview = false,
54
+ hideInput = false,
55
+ disabled = false,
56
+ }: IColorPickerProps) => {
57
+ // Rectangle height is 60% of width for better proportions
58
+ const rectangleHeight = width * 0.6;
59
+
60
+ return (
61
+ <View style={[styles.container, disabled && styles.disabled]}>
62
+ {/* Color picker (circle or rectangle) */}
63
+ <View style={styles.pickerContainer}>
64
+ {variant === 'circle' ? (
65
+ <Saturation
66
+ color={color}
67
+ onChange={onChange}
68
+ onChangeComplete={onChangeComplete}
69
+ size={width}
70
+ thumbSize={thumbSize}
71
+ disabled={disabled}
72
+ />
73
+ ) : (
74
+ <RectangleSaturation
75
+ color={color}
76
+ onChange={onChange}
77
+ onChangeComplete={onChangeComplete}
78
+ width={width}
79
+ height={rectangleHeight}
80
+ thumbSize={thumbSize}
81
+ disabled={disabled}
82
+ />
83
+ )}
84
+ </View>
85
+
86
+ {/* Color preview */}
87
+ {!hidePreview && (
88
+ <View style={styles.previewContainer}>
89
+ <View
90
+ style={[
91
+ styles.preview,
92
+ {
93
+ backgroundColor: color.hex,
94
+ },
95
+ ]}
96
+ />
97
+ <View
98
+ style={[
99
+ styles.previewAlpha,
100
+ {
101
+ backgroundColor: `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.rgb.a})`,
102
+ },
103
+ ]}
104
+ />
105
+ </View>
106
+ )}
107
+
108
+ {/* Sliders section */}
109
+ <View style={styles.slidersContainer}>
110
+ {/* Hue slider - always shown for rectangle variant */}
111
+ {(!hideHue || variant === 'rectangle') && (
112
+ <View style={styles.sliderRow}>
113
+ <Hue
114
+ color={color}
115
+ onChange={onChange}
116
+ onChangeComplete={onChangeComplete}
117
+ barHeight={barHeight}
118
+ thumbSize={thumbSize}
119
+ disabled={disabled}
120
+ />
121
+ </View>
122
+ )}
123
+
124
+ {/* Value/Brightness slider - only for circle variant */}
125
+ {variant === 'circle' && (
126
+ <View style={styles.sliderRow}>
127
+ <Value
128
+ color={color}
129
+ onChange={onChange}
130
+ onChangeComplete={onChangeComplete}
131
+ barHeight={barHeight}
132
+ thumbSize={thumbSize}
133
+ disabled={disabled}
134
+ />
135
+ </View>
136
+ )}
137
+
138
+ {/* Alpha slider */}
139
+ {!hideAlpha && (
140
+ <View style={styles.sliderRow}>
141
+ <Alpha
142
+ color={color}
143
+ onChange={onChange}
144
+ onChangeComplete={onChangeComplete}
145
+ barHeight={barHeight}
146
+ thumbSize={thumbSize}
147
+ disabled={disabled}
148
+ />
149
+ </View>
150
+ )}
151
+ </View>
152
+
153
+ {/* Input fields */}
154
+ {!hideInput && (
155
+ <View style={styles.fieldsContainer}>
156
+ <Fields
157
+ color={color}
158
+ onChange={onChange}
159
+ onChangeComplete={onChangeComplete}
160
+ disabled={disabled}
161
+ />
162
+ </View>
163
+ )}
164
+ </View>
165
+ );
166
+ }
167
+ );
168
+
169
+ const styles = StyleSheet.create({
170
+ container: {
171
+ alignItems: 'center',
172
+ padding: 16,
173
+ },
174
+ disabled: {
175
+ opacity: 0.6,
176
+ },
177
+ pickerContainer: {
178
+ marginBottom: 20,
179
+ },
180
+ previewContainer: {
181
+ flexDirection: 'row',
182
+ marginBottom: 20,
183
+ borderRadius: 8,
184
+ overflow: 'hidden',
185
+ borderWidth: 1,
186
+ borderColor: '#E0E0E0',
187
+ },
188
+ preview: {
189
+ width: 40,
190
+ height: 40,
191
+ },
192
+ previewAlpha: {
193
+ width: 40,
194
+ height: 40,
195
+ },
196
+ slidersContainer: {
197
+ width: '100%',
198
+ gap: 16,
199
+ marginBottom: 20,
200
+ },
201
+ sliderRow: {
202
+ width: '100%',
203
+ },
204
+ fieldsContainer: {
205
+ width: '100%',
206
+ },
207
+ });
208
+
209
+ ColorPicker.displayName = 'ColorPicker';
@@ -0,0 +1,103 @@
1
+ import React, { memo, useState, useCallback, useEffect } from 'react';
2
+ import { View, TextInput, Text, StyleSheet } from 'react-native';
3
+ import type { IFieldsProps } from '../../../core/types';
4
+ import { ColorService } from '../../../core/services';
5
+
6
+ /**
7
+ * Hex color input field
8
+ *
9
+ * Features:
10
+ * - Shows and edits hex value (e.g., #FF5500)
11
+ * - Validates input on blur
12
+ * - Auto-capitalizes and adds # prefix
13
+ */
14
+ export const HexField = memo(
15
+ ({
16
+ color,
17
+ onChange,
18
+ onChangeComplete,
19
+ disabled = false,
20
+ }: IFieldsProps) => {
21
+ const [inputValue, setInputValue] = useState(color.hex);
22
+ const [isFocused, setIsFocused] = useState(false);
23
+
24
+ useEffect(() => {
25
+ if (!isFocused) {
26
+ setInputValue(color.hex);
27
+ }
28
+ }, [color.hex, isFocused]);
29
+
30
+ const handleChangeText = useCallback((text: string) => {
31
+ let value = text.toUpperCase();
32
+ if (!value.startsWith('#')) {
33
+ value = '#' + value;
34
+ }
35
+ value = value.slice(0, 9);
36
+ setInputValue(value);
37
+ }, []);
38
+
39
+ const handleBlur = useCallback(() => {
40
+ setIsFocused(false);
41
+ const hexRegex = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/;
42
+
43
+ if (hexRegex.test(inputValue)) {
44
+ const nextColor = ColorService.convert('hex', inputValue);
45
+ onChange(nextColor);
46
+ onChangeComplete?.(nextColor);
47
+ } else {
48
+ setInputValue(color.hex);
49
+ }
50
+ }, [inputValue, color.hex, onChange, onChangeComplete]);
51
+
52
+ const handleFocus = useCallback(() => {
53
+ setIsFocused(true);
54
+ }, []);
55
+
56
+ return (
57
+ <View style={styles.container}>
58
+ <Text style={styles.label}>HEX</Text>
59
+ <TextInput
60
+ style={[styles.input, disabled && styles.inputDisabled]}
61
+ value={inputValue}
62
+ onChangeText={handleChangeText}
63
+ onBlur={handleBlur}
64
+ onFocus={handleFocus}
65
+ editable={!disabled}
66
+ autoCapitalize="characters"
67
+ autoCorrect={false}
68
+ maxLength={9}
69
+ placeholder="#000000"
70
+ placeholderTextColor="#999999"
71
+ numberOfLines={1}
72
+ />
73
+ </View>
74
+ );
75
+ }
76
+ );
77
+
78
+ const styles = StyleSheet.create({
79
+ container: { flex: 1 },
80
+ label: {
81
+ fontSize: 10,
82
+ fontWeight: '600',
83
+ color: '#666666',
84
+ marginBottom: 4,
85
+ textAlign: 'center',
86
+ },
87
+ input: {
88
+ height: 36,
89
+ borderWidth: 1,
90
+ borderColor: '#E0E0E0',
91
+ borderRadius: 6,
92
+ fontSize: 14,
93
+ color: '#333333',
94
+ backgroundColor: '#FFFFFF',
95
+ textAlign: 'center',
96
+ },
97
+ inputDisabled: {
98
+ backgroundColor: '#F5F5F5',
99
+ color: '#999999',
100
+ },
101
+ });
102
+
103
+ HexField.displayName = 'HexField';
@@ -0,0 +1,138 @@
1
+ import React, { memo, useState, useCallback, useEffect } from 'react';
2
+ import { View, TextInput, Text, StyleSheet } from 'react-native';
3
+ import type { IFieldsProps } from '../../../core/types';
4
+ import { ColorService } from '../../../core/services';
5
+ import { clamp, safeParseInt } from '../../../core/utils';
6
+
7
+ interface RgbInputProps {
8
+ label: string;
9
+ value: number;
10
+ onChange: (value: number) => void;
11
+ onComplete: () => void;
12
+ disabled?: boolean;
13
+ }
14
+
15
+ const RgbInput = memo(
16
+ ({ label, value, onChange, onComplete, disabled }: RgbInputProps) => {
17
+ const [inputValue, setInputValue] = useState(String(value));
18
+ const [isFocused, setIsFocused] = useState(false);
19
+
20
+ useEffect(() => {
21
+ if (!isFocused) {
22
+ setInputValue(String(value));
23
+ }
24
+ }, [value, isFocused]);
25
+
26
+ const handleChangeText = useCallback((text: string) => {
27
+ const numericValue = text.replace(/[^0-9]/g, '');
28
+ setInputValue(numericValue);
29
+ }, []);
30
+
31
+ const handleBlur = useCallback(() => {
32
+ setIsFocused(false);
33
+ const numValue = clamp(safeParseInt(inputValue), 0, 255);
34
+ setInputValue(String(numValue));
35
+ onChange(numValue);
36
+ onComplete();
37
+ }, [inputValue, onChange, onComplete]);
38
+
39
+ const handleFocus = useCallback(() => {
40
+ setIsFocused(true);
41
+ }, []);
42
+
43
+ return (
44
+ <View style={styles.inputContainer}>
45
+ <Text style={styles.label}>{label}</Text>
46
+ <TextInput
47
+ style={[styles.input, disabled && styles.inputDisabled]}
48
+ value={inputValue}
49
+ onChangeText={handleChangeText}
50
+ onBlur={handleBlur}
51
+ onFocus={handleFocus}
52
+ editable={!disabled}
53
+ keyboardType="number-pad"
54
+ maxLength={3}
55
+ placeholder="0"
56
+ placeholderTextColor="#999999"
57
+ />
58
+ </View>
59
+ );
60
+ }
61
+ );
62
+
63
+ /**
64
+ * RGB color input fields
65
+ */
66
+ export const RgbFields = memo(
67
+ ({
68
+ color,
69
+ onChange,
70
+ onChangeComplete,
71
+ disabled = false,
72
+ }: IFieldsProps) => {
73
+ const handleRChange = useCallback(
74
+ (r: number) => {
75
+ const nextColor = ColorService.convert('rgb', { ...color.rgb, r });
76
+ onChange(nextColor);
77
+ },
78
+ [color.rgb, onChange]
79
+ );
80
+
81
+ const handleGChange = useCallback(
82
+ (g: number) => {
83
+ const nextColor = ColorService.convert('rgb', { ...color.rgb, g });
84
+ onChange(nextColor);
85
+ },
86
+ [color.rgb, onChange]
87
+ );
88
+
89
+ const handleBChange = useCallback(
90
+ (b: number) => {
91
+ const nextColor = ColorService.convert('rgb', { ...color.rgb, b });
92
+ onChange(nextColor);
93
+ },
94
+ [color.rgb, onChange]
95
+ );
96
+
97
+ const handleComplete = useCallback(() => {
98
+ onChangeComplete?.(color);
99
+ }, [color, onChangeComplete]);
100
+
101
+ return (
102
+ <View style={styles.container}>
103
+ <RgbInput label="R" value={color.rgb.r} onChange={handleRChange} onComplete={handleComplete} disabled={disabled} />
104
+ <RgbInput label="G" value={color.rgb.g} onChange={handleGChange} onComplete={handleComplete} disabled={disabled} />
105
+ <RgbInput label="B" value={color.rgb.b} onChange={handleBChange} onComplete={handleComplete} disabled={disabled} />
106
+ </View>
107
+ );
108
+ }
109
+ );
110
+
111
+ const styles = StyleSheet.create({
112
+ container: { flexDirection: 'row', gap: 8 },
113
+ inputContainer: { flex: 1 },
114
+ label: {
115
+ fontSize: 10,
116
+ fontWeight: '600',
117
+ color: '#666666',
118
+ marginBottom: 4,
119
+ textAlign: 'center',
120
+ },
121
+ input: {
122
+ height: 36,
123
+ borderWidth: 1,
124
+ borderColor: '#E0E0E0',
125
+ borderRadius: 6,
126
+ paddingHorizontal: 8,
127
+ fontSize: 14,
128
+ color: '#333333',
129
+ backgroundColor: '#FFFFFF',
130
+ textAlign: 'center',
131
+ },
132
+ inputDisabled: {
133
+ backgroundColor: '#F5F5F5',
134
+ color: '#999999',
135
+ },
136
+ });
137
+
138
+ RgbFields.displayName = 'RgbFields';