@zendeskgarden/react-colorpickers 9.0.0-next.7 → 9.0.0-next.9

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 (39) hide show
  1. package/dist/esm/elements/ColorPicker/ColorWell.js +110 -0
  2. package/dist/esm/elements/ColorPicker/index.js +237 -0
  3. package/dist/esm/elements/ColorPicker/reducer.js +275 -0
  4. package/dist/esm/elements/ColorPickerDialog/index.js +154 -0
  5. package/dist/esm/elements/ColorSwatch/index.js +149 -0
  6. package/dist/esm/elements/ColorSwatchDialog/index.js +179 -0
  7. package/dist/esm/index.js +10 -0
  8. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/12/check-sm-fill.svg.js +29 -0
  9. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/16/chevron-down-stroke.svg.js +25 -0
  10. package/dist/esm/styled/ColorPicker/StyledAlphaRange.js +42 -0
  11. package/dist/esm/styled/ColorPicker/StyledColorPicker.js +25 -0
  12. package/dist/esm/styled/ColorPicker/StyledColorWell.js +36 -0
  13. package/dist/esm/styled/ColorPicker/StyledColorWellThumb.js +40 -0
  14. package/dist/esm/styled/ColorPicker/StyledHexField.js +24 -0
  15. package/dist/esm/styled/ColorPicker/StyledHueRange.js +23 -0
  16. package/dist/esm/styled/ColorPicker/StyledInput.js +24 -0
  17. package/dist/esm/styled/ColorPicker/StyledInputGroup.js +22 -0
  18. package/dist/esm/styled/ColorPicker/StyledLabel.js +23 -0
  19. package/dist/esm/styled/ColorPicker/StyledPreview.js +39 -0
  20. package/dist/esm/styled/ColorPicker/StyledRGBAField.js +32 -0
  21. package/dist/esm/styled/ColorPicker/StyledSliderGroup.js +22 -0
  22. package/dist/esm/styled/ColorPicker/StyledSliders.js +23 -0
  23. package/dist/esm/styled/ColorPickerDialog/StyledButton.js +24 -0
  24. package/dist/esm/styled/ColorPickerDialog/StyledButtonPreview.js +51 -0
  25. package/dist/esm/styled/ColorPickerDialog/StyledTooltipBody.js +23 -0
  26. package/dist/esm/styled/ColorPickerDialog/StyledTooltipModal.js +23 -0
  27. package/dist/esm/styled/ColorSwatch/StyledCell.js +22 -0
  28. package/dist/esm/styled/ColorSwatch/StyledColorSwatch.js +22 -0
  29. package/dist/esm/styled/ColorSwatch/StyledColorSwatchInput.js +22 -0
  30. package/dist/esm/styled/ColorSwatch/StyledColorSwatchLabel.js +40 -0
  31. package/dist/esm/styled/ColorSwatch/StyledIcon.js +24 -0
  32. package/dist/esm/styled/common/StyledRange.js +151 -0
  33. package/dist/esm/utils/conversion.js +34 -0
  34. package/dist/esm/utils/saturation.js +64 -0
  35. package/dist/esm/utils/validation.js +12 -0
  36. package/dist/index.cjs.js +59 -81
  37. package/package.json +9 -9
  38. package/dist/index.esm.js +0 -1605
  39. package/dist/typings/styled/common/checkeredBackground.d.ts +0 -8
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { useContext, useRef, useState, useEffect, useMemo, useCallback } from 'react';
8
+ import throttle from 'lodash.throttle';
9
+ import { ThemeContext } from 'styled-components';
10
+ import { hslToHsv } from '../../utils/conversion.js';
11
+ import { getThumbPosition, getNextHsv } from '../../utils/saturation.js';
12
+ import '../../styled/ColorPicker/StyledColorPicker.js';
13
+ import '../../styled/ColorPicker/StyledHueRange.js';
14
+ import '../../styled/ColorPicker/StyledAlphaRange.js';
15
+ import '../../styled/ColorPicker/StyledPreview.js';
16
+ import { StyledColorWell } from '../../styled/ColorPicker/StyledColorWell.js';
17
+ import { StyledColorWellThumb } from '../../styled/ColorPicker/StyledColorWellThumb.js';
18
+ import '../../styled/ColorPicker/StyledSliderGroup.js';
19
+ import '../../styled/ColorPicker/StyledHexField.js';
20
+ import '../../styled/ColorPicker/StyledLabel.js';
21
+ import '../../styled/ColorPicker/StyledInput.js';
22
+ import '../../styled/ColorPicker/StyledInputGroup.js';
23
+ import '../../styled/ColorPicker/StyledRGBAField.js';
24
+ import '../../styled/ColorPicker/StyledSliders.js';
25
+ import '../../styled/ColorPickerDialog/StyledButton.js';
26
+ import '../../styled/ColorPickerDialog/StyledButtonPreview.js';
27
+ import '../../styled/ColorPickerDialog/StyledTooltipModal.js';
28
+ import '../../styled/ColorPickerDialog/StyledTooltipBody.js';
29
+ import '../../styled/ColorSwatch/StyledColorSwatch.js';
30
+ import '../../styled/ColorSwatch/StyledColorSwatchInput.js';
31
+ import '../../styled/ColorSwatch/StyledColorSwatchLabel.js';
32
+ import '../../styled/ColorSwatch/StyledIcon.js';
33
+ import '../../styled/ColorSwatch/StyledCell.js';
34
+
35
+ const ColorWell = React__default.memo(_ref => {
36
+ let {
37
+ hue,
38
+ saturation,
39
+ lightness,
40
+ onChange
41
+ } = _ref;
42
+ const {
43
+ rtl
44
+ } = useContext(ThemeContext);
45
+ const containerRef = useRef(null);
46
+ const hsv = hslToHsv(hue, saturation, lightness);
47
+ const mouseActiveRef = useRef(false);
48
+ const [x, setX] = useState(0);
49
+ const [y, setY] = useState(0);
50
+ const {
51
+ topFromMouse,
52
+ leftFromMouse
53
+ } = getThumbPosition(x, y, rtl, containerRef);
54
+ const [topPosition, setTopPosition] = useState(0);
55
+ const [leftPosition, setLeftPosition] = useState(0);
56
+ useEffect(() => {
57
+ setTopPosition(100 - hsv.v);
58
+ setLeftPosition(rtl ? 100 - hsv.s : hsv.s);
59
+ }, [hsv.s, hsv.v, rtl]);
60
+ const throttledChange = useMemo(() => {
61
+ return throttle(e => {
62
+ if (containerRef.current) {
63
+ const nextHsv = getNextHsv(e, hue, containerRef.current, rtl);
64
+ onChange && onChange(nextHsv, e);
65
+ }
66
+ }, 50);
67
+ }, [hue, rtl, onChange]);
68
+ const handleMouseMove = useCallback(e => {
69
+ mouseActiveRef.current = true;
70
+ setX(e.pageX);
71
+ setY(e.pageY);
72
+ throttledChange(e);
73
+ }, [throttledChange]);
74
+ const handleMouseUp = useCallback(() => {
75
+ mouseActiveRef.current = true;
76
+ setTimeout(() => {
77
+ mouseActiveRef.current = false;
78
+ });
79
+ throttledChange.cancel();
80
+ window.removeEventListener('mousemove', handleMouseMove);
81
+ window.removeEventListener('mouseup', handleMouseUp);
82
+ }, [throttledChange, handleMouseMove]);
83
+ const handleMouseDown = useCallback(e => {
84
+ mouseActiveRef.current = true;
85
+ e.persist();
86
+ handleMouseMove(e);
87
+ throttledChange(e);
88
+ window.addEventListener('mousemove', handleMouseMove);
89
+ window.addEventListener('mouseup', handleMouseUp);
90
+ }, [throttledChange, handleMouseMove, handleMouseUp]);
91
+ useEffect(() => {
92
+ return () => {
93
+ throttledChange.cancel();
94
+ };
95
+ }, [throttledChange]);
96
+ return (
97
+ React__default.createElement(StyledColorWell, {
98
+ hue: hue,
99
+ ref: containerRef,
100
+ role: "presentation",
101
+ onMouseDown: handleMouseDown
102
+ }, React__default.createElement(StyledColorWellThumb, {
103
+ top: mouseActiveRef.current ? topFromMouse : topPosition,
104
+ left: mouseActiveRef.current ? leftFromMouse : leftPosition
105
+ }))
106
+ );
107
+ });
108
+ ColorWell.displayName = 'ColorWell';
109
+
110
+ export { ColorWell };
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { forwardRef, useReducer, useRef, useMemo, useEffect, useCallback } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { Field } from '@zendeskgarden/react-forms';
10
+ import { ColorWell } from './ColorWell.js';
11
+ import { StyledColorPicker } from '../../styled/ColorPicker/StyledColorPicker.js';
12
+ import { StyledHueRange } from '../../styled/ColorPicker/StyledHueRange.js';
13
+ import { StyledAlphaRange } from '../../styled/ColorPicker/StyledAlphaRange.js';
14
+ import { StyledPreview } from '../../styled/ColorPicker/StyledPreview.js';
15
+ import '../../styled/ColorPicker/StyledColorWell.js';
16
+ import '../../styled/ColorPicker/StyledColorWellThumb.js';
17
+ import { StyledSliderGroup } from '../../styled/ColorPicker/StyledSliderGroup.js';
18
+ import { StyledHexField } from '../../styled/ColorPicker/StyledHexField.js';
19
+ import { StyledLabel } from '../../styled/ColorPicker/StyledLabel.js';
20
+ import { StyledInput } from '../../styled/ColorPicker/StyledInput.js';
21
+ import { StyledInputGroup } from '../../styled/ColorPicker/StyledInputGroup.js';
22
+ import { StyledRGBAField } from '../../styled/ColorPicker/StyledRGBAField.js';
23
+ import { StyledSliders } from '../../styled/ColorPicker/StyledSliders.js';
24
+ import '../../styled/ColorPickerDialog/StyledButton.js';
25
+ import '../../styled/ColorPickerDialog/StyledButtonPreview.js';
26
+ import '../../styled/ColorPickerDialog/StyledTooltipModal.js';
27
+ import '../../styled/ColorPickerDialog/StyledTooltipBody.js';
28
+ import '../../styled/ColorSwatch/StyledColorSwatch.js';
29
+ import '../../styled/ColorSwatch/StyledColorSwatchInput.js';
30
+ import '../../styled/ColorSwatch/StyledColorSwatchLabel.js';
31
+ import '../../styled/ColorSwatch/StyledIcon.js';
32
+ import '../../styled/ColorSwatch/StyledCell.js';
33
+ import { reducer, getInitialState, convertStringToColor, areColorsEqual } from './reducer.js';
34
+
35
+ const ColorPicker = forwardRef((_ref, ref) => {
36
+ let {
37
+ color,
38
+ defaultColor,
39
+ isOpaque,
40
+ labels = {},
41
+ autofocus,
42
+ onChange,
43
+ ...props
44
+ } = _ref;
45
+ const [state, dispatch] = useReducer(reducer, getInitialState(color || defaultColor));
46
+ const previousComputedColorRef = useRef(state.color);
47
+ const previousStateColorRef = useRef(state.color);
48
+ const computedColor = useMemo(() => {
49
+ let retVal = state.color;
50
+ if (color) {
51
+ if (typeof color === 'string') {
52
+ const convertedColor = convertStringToColor(color);
53
+ if (convertedColor) {
54
+ retVal = convertedColor;
55
+ }
56
+ } else {
57
+ retVal = color;
58
+ }
59
+ }
60
+ if (isOpaque) {
61
+ retVal.alpha = 100;
62
+ }
63
+ if (areColorsEqual(retVal, previousComputedColorRef.current)) {
64
+ return previousComputedColorRef.current;
65
+ }
66
+ return retVal;
67
+ }, [color, isOpaque, state.color]);
68
+ useEffect(() => {
69
+ if (!areColorsEqual(previousStateColorRef.current, state.color) && !areColorsEqual(color, state.color)) {
70
+ onChange && onChange(state.color);
71
+ }
72
+ previousStateColorRef.current = state.color;
73
+ }, [color, onChange, state.color]);
74
+ if (previousComputedColorRef.current !== computedColor) {
75
+ dispatch({
76
+ type: 'RESET_COLOR',
77
+ payload: computedColor
78
+ });
79
+ previousComputedColorRef.current = computedColor;
80
+ }
81
+ const handleColorWellChange = useCallback(hsv => {
82
+ dispatch({
83
+ type: 'SATURATION_CHANGE',
84
+ payload: hsv
85
+ });
86
+ }, []);
87
+ const handleHueChange = useCallback(e => {
88
+ dispatch({
89
+ type: 'HUE_CHANGE',
90
+ payload: e.target.value
91
+ });
92
+ }, []);
93
+ const handleAlphaSliderChange = useCallback(e => {
94
+ dispatch({
95
+ type: 'ALPHA_SLIDER_CHANGE',
96
+ payload: e.target.value
97
+ });
98
+ }, []);
99
+ const handleHexChange = useCallback(e => {
100
+ dispatch({
101
+ type: 'HEX_CHANGE',
102
+ payload: e.target.value
103
+ });
104
+ }, []);
105
+ const handleRedChange = useCallback(e => {
106
+ dispatch({
107
+ type: 'RED_CHANGE',
108
+ payload: e.target.value
109
+ });
110
+ }, []);
111
+ const handleGreenChange = useCallback(e => {
112
+ dispatch({
113
+ type: 'GREEN_CHANGE',
114
+ payload: e.target.value
115
+ });
116
+ }, []);
117
+ const handleBlueChange = useCallback(e => {
118
+ dispatch({
119
+ type: 'BLUE_CHANGE',
120
+ payload: e.target.value
121
+ });
122
+ }, []);
123
+ const handleAlphaChange = useCallback(e => {
124
+ dispatch({
125
+ type: 'ALPHA_CHANGE',
126
+ payload: e.target.value
127
+ });
128
+ }, []);
129
+ const handleBlur = useCallback(() => {
130
+ dispatch({
131
+ type: 'RESET_COLOR',
132
+ payload: computedColor
133
+ });
134
+ }, [computedColor]);
135
+ return React__default.createElement(StyledColorPicker, Object.assign({
136
+ ref: ref,
137
+ isOpaque: isOpaque
138
+ }, props), React__default.createElement(ColorWell, {
139
+ hue: computedColor.hue,
140
+ saturation: computedColor.saturation,
141
+ lightness: computedColor.lightness,
142
+ onChange: handleColorWellChange
143
+ }), React__default.createElement(StyledSliderGroup, null, React__default.createElement(StyledPreview, {
144
+ red: computedColor.red,
145
+ green: computedColor.green,
146
+ blue: computedColor.blue,
147
+ alpha: computedColor.alpha,
148
+ isOpaque: isOpaque
149
+ }), React__default.createElement(StyledSliders, {
150
+ isOpaque: isOpaque
151
+ }, React__default.createElement(Field, null, React__default.createElement(Field.Label, {
152
+ hidden: true
153
+ }, labels.hueSlider || 'Hue slider'), React__default.createElement(StyledHueRange, {
154
+ step: 1,
155
+ max: 360,
156
+ value: computedColor.hue,
157
+ isOpaque: isOpaque,
158
+ onChange: handleHueChange
159
+ })), !isOpaque && React__default.createElement(Field, null, React__default.createElement(Field.Label, {
160
+ hidden: true
161
+ }, labels.alphaSlider || 'Alpha slider'), React__default.createElement(StyledAlphaRange, {
162
+ max: 1,
163
+ step: 0.01,
164
+ value: computedColor.alpha / 100,
165
+ onChange: handleAlphaSliderChange,
166
+ red: computedColor.red,
167
+ green: computedColor.green,
168
+ blue: computedColor.blue
169
+ })))), React__default.createElement(StyledInputGroup, null, React__default.createElement(StyledHexField, null, React__default.createElement(StyledLabel, {
170
+ isRegular: true
171
+ }, labels.hex || 'Hex'), React__default.createElement(StyledInput, {
172
+ isCompact: true,
173
+ maxLength: 7,
174
+ value: state.hexInput
175
+ ,
176
+ autoFocus: autofocus,
177
+ spellCheck: false,
178
+ onBlur: handleBlur,
179
+ onChange: handleHexChange
180
+ })), React__default.createElement(StyledRGBAField, null, React__default.createElement(StyledLabel, {
181
+ isRegular: true
182
+ }, labels.red || 'R'), React__default.createElement(StyledInput, {
183
+ isCompact: true,
184
+ type: "number",
185
+ min: "0",
186
+ max: "255",
187
+ maxLength: 3,
188
+ value: state.redInput,
189
+ onBlur: handleBlur,
190
+ onChange: handleRedChange
191
+ })), React__default.createElement(StyledRGBAField, null, React__default.createElement(StyledLabel, {
192
+ isRegular: true
193
+ }, labels.green || 'G'), React__default.createElement(StyledInput, {
194
+ isCompact: true,
195
+ type: "number",
196
+ min: "0",
197
+ max: "255",
198
+ maxLength: 3,
199
+ value: state.greenInput,
200
+ onBlur: handleBlur,
201
+ onChange: handleGreenChange
202
+ })), React__default.createElement(StyledRGBAField, null, React__default.createElement(StyledLabel, {
203
+ isRegular: true
204
+ }, labels.blue || 'B'), React__default.createElement(StyledInput, {
205
+ isCompact: true,
206
+ type: "number",
207
+ min: "0",
208
+ max: "255",
209
+ maxLength: 3,
210
+ value: state.blueInput,
211
+ onBlur: handleBlur,
212
+ onChange: handleBlueChange
213
+ })), !isOpaque && React__default.createElement(StyledRGBAField, null, React__default.createElement(StyledLabel, {
214
+ isRegular: true
215
+ }, labels.alpha || 'A'), React__default.createElement(StyledInput, {
216
+ isCompact: true,
217
+ type: "number",
218
+ min: "0",
219
+ max: "100",
220
+ value: state.alphaInput,
221
+ onBlur: handleBlur,
222
+ onChange: handleAlphaChange
223
+ }))));
224
+ });
225
+ ColorPicker.defaultProps = {
226
+ defaultColor: '#fff'
227
+ };
228
+ ColorPicker.displayName = 'ColorPicker';
229
+ ColorPicker.propTypes = {
230
+ color: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
231
+ isOpaque: PropTypes.bool,
232
+ onChange: PropTypes.func,
233
+ labels: PropTypes.object,
234
+ defaultColor: PropTypes.oneOfType([PropTypes.object, PropTypes.string])
235
+ };
236
+
237
+ export { ColorPicker };
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import isEqual from 'lodash.isequal';
8
+ import { parseToHsl, parseToRgb, rgb, hsl } from 'polished';
9
+ import { hsvToHsl } from '../../utils/conversion.js';
10
+ import { isValidHex } from '../../utils/validation.js';
11
+
12
+ function convertStringToColor(colorString) {
13
+ if (colorString.includes('#') && !isValidHex(colorString)) {
14
+ return undefined;
15
+ }
16
+ const {
17
+ hue,
18
+ saturation,
19
+ lightness
20
+ } = parseToHsl(colorString);
21
+ const {
22
+ red,
23
+ green,
24
+ blue,
25
+ alpha
26
+ } = parseToRgb(colorString);
27
+ const computedAlpha = alpha === undefined ? 100 : alpha * 100;
28
+ const computedHex = rgb({
29
+ red,
30
+ green,
31
+ blue
32
+ });
33
+ return {
34
+ hue,
35
+ saturation: saturation * 100,
36
+ lightness: lightness * 100,
37
+ red,
38
+ green,
39
+ blue,
40
+ alpha: computedAlpha,
41
+ hex: computedHex
42
+ };
43
+ }
44
+ const areColorsEqual = (a, b) => {
45
+ if (a === undefined || b === undefined) {
46
+ return false;
47
+ }
48
+ const colorA = typeof a === 'string' ? convertStringToColor(a) : a;
49
+ const colorB = typeof b === 'string' ? convertStringToColor(b) : b;
50
+ if (colorA === undefined || colorB === undefined) {
51
+ return false;
52
+ }
53
+ return isEqual(colorA, colorB);
54
+ };
55
+ function getInitialState(color) {
56
+ const whiteColor = {
57
+ hue: 0,
58
+ saturation: 0,
59
+ lightness: 0,
60
+ red: 255,
61
+ green: 255,
62
+ blue: 255,
63
+ alpha: 100,
64
+ hex: '#ffffff'
65
+ };
66
+ if (color === undefined) {
67
+ return getInitialState(whiteColor);
68
+ }
69
+ if (typeof color === 'string') {
70
+ const computedColor = convertStringToColor(color);
71
+ return getInitialState(computedColor || whiteColor);
72
+ }
73
+ return {
74
+ color,
75
+ hexInput: color.hex,
76
+ redInput: color.red.toString(),
77
+ blueInput: color.blue.toString(),
78
+ greenInput: color.green.toString(),
79
+ alphaInput: color.alpha.toString()
80
+ };
81
+ }
82
+ const reducer = (state, action) => {
83
+ switch (action.type) {
84
+ case 'SATURATION_CHANGE':
85
+ {
86
+ const hsl$1 = hsvToHsl(action.payload.h, action.payload.s * 100, action.payload.v * 100);
87
+ const hex = hsl({
88
+ hue: action.payload.h,
89
+ saturation: hsl$1.s / 100,
90
+ lightness: hsl$1.l / 100
91
+ });
92
+ const rgb = parseToRgb(hex);
93
+ return {
94
+ ...state,
95
+ color: {
96
+ ...state.color,
97
+ saturation: hsl$1.s,
98
+ lightness: hsl$1.l,
99
+ hex,
100
+ red: rgb.red,
101
+ green: rgb.green,
102
+ blue: rgb.blue
103
+ }
104
+ };
105
+ }
106
+ case 'HUE_CHANGE':
107
+ {
108
+ const hue = Number(action.payload);
109
+ const hex = hsl({
110
+ hue,
111
+ saturation: state.color.saturation / 100,
112
+ lightness: state.color.lightness / 100
113
+ });
114
+ const rgb = parseToRgb(hex);
115
+ return {
116
+ ...state,
117
+ color: {
118
+ ...state.color,
119
+ hue,
120
+ hex,
121
+ red: rgb.red,
122
+ green: rgb.green,
123
+ blue: rgb.blue
124
+ }
125
+ };
126
+ }
127
+ case 'ALPHA_SLIDER_CHANGE':
128
+ {
129
+ return {
130
+ ...state,
131
+ color: {
132
+ ...state.color,
133
+ alpha: Math.round(Number(action.payload) * 100)
134
+ }
135
+ };
136
+ }
137
+ case 'HEX_CHANGE':
138
+ {
139
+ let color = state.color;
140
+ if (isValidHex(action.payload)) {
141
+ const rgb = parseToRgb(action.payload);
142
+ const hsl = parseToHsl(`rgb(${rgb.red}, ${rgb.green}, ${rgb.blue})`);
143
+ color = {
144
+ ...color,
145
+ hue: hsl.hue,
146
+ saturation: hsl.saturation * 100,
147
+ lightness: hsl.lightness * 100,
148
+ hex: action.payload,
149
+ red: rgb.red,
150
+ green: rgb.green,
151
+ blue: rgb.blue
152
+ };
153
+ }
154
+ return {
155
+ ...state,
156
+ hexInput: action.payload,
157
+ color
158
+ };
159
+ }
160
+ case 'RED_CHANGE':
161
+ {
162
+ let red = parseInt(action.payload, 10);
163
+ let color = state.color;
164
+ if (!isNaN(red)) {
165
+ if (red >= 255) {
166
+ red = 255;
167
+ }
168
+ if (red < 0) {
169
+ red = 0;
170
+ }
171
+ const hsl = parseToHsl(`rgb(${red}, ${color.green}, ${color.blue})`);
172
+ const hex = rgb(red, color.green, color.blue);
173
+ color = {
174
+ ...color,
175
+ hex,
176
+ red: action.payload === '' ? color.red : red,
177
+ hue: hsl.hue,
178
+ saturation: hsl.saturation * 100,
179
+ lightness: hsl.lightness * 100
180
+ };
181
+ }
182
+ return {
183
+ ...state,
184
+ redInput: action.payload,
185
+ color
186
+ };
187
+ }
188
+ case 'GREEN_CHANGE':
189
+ {
190
+ let green = parseInt(action.payload, 10);
191
+ let color = state.color;
192
+ if (!isNaN(green)) {
193
+ if (green >= 255) {
194
+ green = 255;
195
+ }
196
+ if (green < 0) {
197
+ green = 0;
198
+ }
199
+ const hsl = parseToHsl(`rgb(${color.red}, ${green}, ${color.blue})`);
200
+ const hex = rgb(color.red, green, color.blue);
201
+ color = {
202
+ ...color,
203
+ hex,
204
+ green: action.payload === '' ? color.green : green,
205
+ hue: hsl.hue,
206
+ saturation: hsl.saturation * 100,
207
+ lightness: hsl.lightness * 100
208
+ };
209
+ }
210
+ return {
211
+ ...state,
212
+ greenInput: action.payload,
213
+ color
214
+ };
215
+ }
216
+ case 'BLUE_CHANGE':
217
+ {
218
+ let blue = parseInt(action.payload, 10);
219
+ let color = state.color;
220
+ if (!isNaN(blue)) {
221
+ if (blue >= 255) {
222
+ blue = 255;
223
+ }
224
+ if (blue < 0) {
225
+ blue = 0;
226
+ }
227
+ const hsl = parseToHsl(`rgb(${color.red}, ${color.green}, ${blue})`);
228
+ const hex = rgb(color.red, color.green, blue);
229
+ color = {
230
+ ...color,
231
+ hex,
232
+ blue: action.payload === '' ? color.blue : blue,
233
+ hue: hsl.hue,
234
+ saturation: hsl.saturation * 100,
235
+ lightness: hsl.lightness * 100
236
+ };
237
+ }
238
+ return {
239
+ ...state,
240
+ blueInput: action.payload,
241
+ color
242
+ };
243
+ }
244
+ case 'ALPHA_CHANGE':
245
+ {
246
+ let alpha = parseInt(action.payload, 10);
247
+ let color = state.color;
248
+ if (!isNaN(alpha)) {
249
+ if (alpha > 100) {
250
+ alpha = 100;
251
+ }
252
+ if (alpha < 0) {
253
+ alpha = 0;
254
+ }
255
+ color = {
256
+ ...color,
257
+ alpha
258
+ };
259
+ }
260
+ return {
261
+ ...state,
262
+ alphaInput: action.payload,
263
+ color
264
+ };
265
+ }
266
+ case 'RESET_COLOR':
267
+ {
268
+ return getInitialState(action.payload);
269
+ }
270
+ default:
271
+ throw new Error('Unknown reducer case.');
272
+ }
273
+ };
274
+
275
+ export { areColorsEqual, convertStringToColor, getInitialState, reducer };