@react-stately/color 3.6.2-nightly.4664 → 3.6.2-nightly.4666
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/dist/Color.main.js +5 -1
- package/dist/Color.main.js.map +1 -1
- package/dist/Color.mjs +5 -1
- package/dist/Color.module.js +5 -1
- package/dist/Color.module.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/useColorAreaState.main.js +8 -5
- package/dist/useColorAreaState.main.js.map +1 -1
- package/dist/useColorAreaState.mjs +8 -5
- package/dist/useColorAreaState.module.js +8 -5
- package/dist/useColorAreaState.module.js.map +1 -1
- package/dist/useColorFieldState.main.js +2 -1
- package/dist/useColorFieldState.main.js.map +1 -1
- package/dist/useColorFieldState.mjs +2 -1
- package/dist/useColorFieldState.module.js +2 -1
- package/dist/useColorFieldState.module.js.map +1 -1
- package/dist/useColorSliderState.main.js +6 -2
- package/dist/useColorSliderState.main.js.map +1 -1
- package/dist/useColorSliderState.mjs +6 -2
- package/dist/useColorSliderState.module.js +6 -2
- package/dist/useColorSliderState.module.js.map +1 -1
- package/dist/useColorWheelState.main.js +6 -3
- package/dist/useColorWheelState.main.js.map +1 -1
- package/dist/useColorWheelState.mjs +6 -3
- package/dist/useColorWheelState.module.js +6 -3
- package/dist/useColorWheelState.module.js.map +1 -1
- package/package.json +11 -11
- package/src/Color.ts +13 -7
- package/src/useColorAreaState.ts +13 -6
- package/src/useColorFieldState.ts +8 -4
- package/src/useColorSliderState.ts +10 -2
- package/src/useColorWheelState.ts +10 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-stately/color",
|
|
3
|
-
"version": "3.6.2-nightly.
|
|
3
|
+
"version": "3.6.2-nightly.4666+bd458c1ed",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@internationalized/number": "3.5.4-nightly.
|
|
26
|
-
"@internationalized/string": "3.2.4-nightly.
|
|
27
|
-
"@react-aria/i18n": "3.0.0-nightly.
|
|
28
|
-
"@react-stately/form": "3.0.4-nightly.
|
|
29
|
-
"@react-stately/numberfield": "3.0.0-nightly.
|
|
30
|
-
"@react-stately/slider": "3.5.5-nightly.
|
|
31
|
-
"@react-stately/utils": "3.0.0-nightly.
|
|
32
|
-
"@react-types/color": "3.0.0-nightly.
|
|
33
|
-
"@react-types/shared": "3.0.0-nightly.
|
|
25
|
+
"@internationalized/number": "3.5.4-nightly.4666+bd458c1ed",
|
|
26
|
+
"@internationalized/string": "3.2.4-nightly.4666+bd458c1ed",
|
|
27
|
+
"@react-aria/i18n": "3.0.0-nightly.2954+bd458c1ed",
|
|
28
|
+
"@react-stately/form": "3.0.4-nightly.4666+bd458c1ed",
|
|
29
|
+
"@react-stately/numberfield": "3.0.0-nightly.2954+bd458c1ed",
|
|
30
|
+
"@react-stately/slider": "3.5.5-nightly.4666+bd458c1ed",
|
|
31
|
+
"@react-stately/utils": "3.0.0-nightly.2954+bd458c1ed",
|
|
32
|
+
"@react-types/color": "3.0.0-nightly.4666+bd458c1ed",
|
|
33
|
+
"@react-types/shared": "3.0.0-nightly.2954+bd458c1ed",
|
|
34
34
|
"@swc/helpers": "^0.5.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "bd458c1ed166a5ff1fd93f0c1a397e1540b3d880"
|
|
43
43
|
}
|
package/src/Color.ts
CHANGED
|
@@ -120,9 +120,9 @@ abstract class Color implements IColor {
|
|
|
120
120
|
|
|
121
121
|
getColorSpaceAxes(xyChannels: {xChannel?: ColorChannel, yChannel?: ColorChannel}): ColorAxes {
|
|
122
122
|
let {xChannel, yChannel} = xyChannels;
|
|
123
|
-
let xCh = xChannel || this.getColorChannels().find(c => c !== yChannel)
|
|
124
|
-
let yCh = yChannel || this.getColorChannels().find(c => c !== xCh)
|
|
125
|
-
let zCh = this.getColorChannels().find(c => c !== xCh && c !== yCh)
|
|
123
|
+
let xCh = xChannel || this.getColorChannels().find(c => c !== yChannel)!;
|
|
124
|
+
let yCh = yChannel || this.getColorChannels().find(c => c !== xCh)!;
|
|
125
|
+
let zCh = this.getColorChannels().find(c => c !== xCh && c !== yCh)!;
|
|
126
126
|
|
|
127
127
|
return {xChannel: xCh, yChannel: yCh, zChannel: zCh};
|
|
128
128
|
}
|
|
@@ -245,7 +245,7 @@ class RGBColor extends Color {
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
static parse(value: string) {
|
|
248
|
-
let colors = [];
|
|
248
|
+
let colors: Array<number | undefined> = [];
|
|
249
249
|
// matching #rgb, #rgba, #rrggbb, #rrggbbaa
|
|
250
250
|
if (/^#[\da-f]+$/i.test(value) && [4, 5, 7, 9].includes(value.length)) {
|
|
251
251
|
const values = (value.length < 6 ? value.replace(/[^#]/gi, '$&$&') : value).slice(1).split('');
|
|
@@ -259,7 +259,12 @@ class RGBColor extends Color {
|
|
|
259
259
|
const match = value.match(/^rgba?\((.*)\)$/);
|
|
260
260
|
if (match?.[1]) {
|
|
261
261
|
colors = match[1].split(',').map(value => Number(value.trim()));
|
|
262
|
-
colors = colors.map((num, i) =>
|
|
262
|
+
colors = colors.map((num, i) => {
|
|
263
|
+
return clamp(num ?? 0, 0, i < 3 ? 255 : 1);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
if (colors[0] === undefined || colors[1] === undefined || colors[2] === undefined) {
|
|
267
|
+
return undefined;
|
|
263
268
|
}
|
|
264
269
|
|
|
265
270
|
return colors.length < 3 ? undefined : new RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1);
|
|
@@ -371,6 +376,7 @@ class RGBColor extends Color {
|
|
|
371
376
|
hue = (blue - red) / chroma + 2;
|
|
372
377
|
break;
|
|
373
378
|
case blue:
|
|
379
|
+
default:
|
|
374
380
|
hue = (red - green) / chroma + 4;
|
|
375
381
|
break;
|
|
376
382
|
}
|
|
@@ -443,7 +449,7 @@ class HSBColor extends Color {
|
|
|
443
449
|
}
|
|
444
450
|
|
|
445
451
|
static parse(value: string): HSBColor | void {
|
|
446
|
-
let m: RegExpMatchArray |
|
|
452
|
+
let m: RegExpMatchArray | null;
|
|
447
453
|
if ((m = value.match(HSB_REGEX))) {
|
|
448
454
|
const [h, s, b, a] = (m[1] ?? m[2]).split(',').map(n => Number(n.trim().replace('%', '')));
|
|
449
455
|
return new HSBColor(normalizeHue(h), clamp(s, 0, 100), clamp(b, 0, 100), clamp(a ?? 1, 0, 1));
|
|
@@ -582,7 +588,7 @@ class HSLColor extends Color {
|
|
|
582
588
|
}
|
|
583
589
|
|
|
584
590
|
static parse(value: string): HSLColor | void {
|
|
585
|
-
let m: RegExpMatchArray |
|
|
591
|
+
let m: RegExpMatchArray | null;
|
|
586
592
|
if ((m = value.match(HSL_REGEX))) {
|
|
587
593
|
const [h, s, l, a] = (m[1] ?? m[2]).split(',').map(n => Number(n.trim().replace('%', '')));
|
|
588
594
|
return new HSLColor(normalizeHue(h), clamp(s, 0, 100), clamp(l, 0, 100), clamp(a ?? 1, 0, 1));
|
package/src/useColorAreaState.ts
CHANGED
|
@@ -85,8 +85,15 @@ export function useColorAreaState(props: ColorAreaProps): ColorAreaState {
|
|
|
85
85
|
if (!value && !defaultValue) {
|
|
86
86
|
defaultValue = DEFAULT_COLOR;
|
|
87
87
|
}
|
|
88
|
+
if (value) {
|
|
89
|
+
value = normalizeColor(value);
|
|
90
|
+
}
|
|
91
|
+
if (defaultValue) {
|
|
92
|
+
defaultValue = normalizeColor(defaultValue);
|
|
93
|
+
}
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
// safe to cast value and defaultValue to Color, one of them will always be defined because if neither are, we assign a default
|
|
96
|
+
let [colorValue, setColorState] = useControlledState<Color>(value as Color, defaultValue as Color, onChange);
|
|
90
97
|
let color = useMemo(() => colorSpace && colorValue ? colorValue.toFormat(colorSpace) : colorValue, [colorValue, colorSpace]);
|
|
91
98
|
let valueRef = useRef(color);
|
|
92
99
|
let setColor = (color: Color) => {
|
|
@@ -141,7 +148,7 @@ export function useColorAreaState(props: ColorAreaProps): ColorAreaState {
|
|
|
141
148
|
setColorFromPoint(x: number, y: number) {
|
|
142
149
|
let newXValue = minValueX + clamp(x, 0, 1) * (maxValueX - minValueX);
|
|
143
150
|
let newYValue = minValueY + (1 - clamp(y, 0, 1)) * (maxValueY - minValueY);
|
|
144
|
-
let newColor:Color;
|
|
151
|
+
let newColor: Color | undefined;
|
|
145
152
|
if (newXValue !== xValue) {
|
|
146
153
|
// Round new value to multiple of step, clamp value between min and max
|
|
147
154
|
newXValue = snapValueToStep(newXValue, minValueX, maxValueX, stepX);
|
|
@@ -161,16 +168,16 @@ export function useColorAreaState(props: ColorAreaProps): ColorAreaState {
|
|
|
161
168
|
let y = 1 - (yValue - minValueY) / (maxValueY - minValueY);
|
|
162
169
|
return {x, y};
|
|
163
170
|
},
|
|
164
|
-
incrementX(stepSize) {
|
|
171
|
+
incrementX(stepSize = 1) {
|
|
165
172
|
setXValue(xValue + stepSize > maxValueX ? maxValueX : snapValueToStep(xValue + stepSize, minValueX, maxValueX, stepX));
|
|
166
173
|
},
|
|
167
|
-
incrementY(stepSize) {
|
|
174
|
+
incrementY(stepSize = 1) {
|
|
168
175
|
setYValue(yValue + stepSize > maxValueY ? maxValueY : snapValueToStep(yValue + stepSize, minValueY, maxValueY, stepY));
|
|
169
176
|
},
|
|
170
|
-
decrementX(stepSize) {
|
|
177
|
+
decrementX(stepSize = 1) {
|
|
171
178
|
setXValue(snapValueToStep(xValue - stepSize, minValueX, maxValueX, stepX));
|
|
172
179
|
},
|
|
173
|
-
decrementY(stepSize) {
|
|
180
|
+
decrementY(stepSize = 1) {
|
|
174
181
|
setYValue(snapValueToStep(yValue - stepSize, minValueY, maxValueY, stepY));
|
|
175
182
|
},
|
|
176
183
|
setDragging(isDragging) {
|
|
@@ -27,7 +27,7 @@ export interface ColorFieldState extends FormValidationState {
|
|
|
27
27
|
* The currently parsed color value, or null if the field is empty.
|
|
28
28
|
* Updated based on the `inputValue` as the user types.
|
|
29
29
|
*/
|
|
30
|
-
readonly colorValue: Color,
|
|
30
|
+
readonly colorValue: Color | null,
|
|
31
31
|
/** Sets the current text value of the input. */
|
|
32
32
|
setInputValue(value: string): void,
|
|
33
33
|
/**
|
|
@@ -72,7 +72,7 @@ export function useColorFieldState(
|
|
|
72
72
|
|
|
73
73
|
let initialValue = useColor(value);
|
|
74
74
|
let initialDefaultValue = useColor(defaultValue);
|
|
75
|
-
let [colorValue, setColorValue] = useControlledState<Color>(initialValue
|
|
75
|
+
let [colorValue, setColorValue] = useControlledState<Color | null>(initialValue!, initialDefaultValue!, onChange);
|
|
76
76
|
let [inputValue, setInputValue] = useState(() => (value || defaultValue) && colorValue ? colorValue.toString('hex') : '');
|
|
77
77
|
|
|
78
78
|
let validation = useFormValidationState({
|
|
@@ -80,7 +80,7 @@ export function useColorFieldState(
|
|
|
80
80
|
value: colorValue
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
let safelySetColorValue = (newColor: Color) => {
|
|
83
|
+
let safelySetColorValue = (newColor: Color | null) => {
|
|
84
84
|
if (!colorValue || !newColor) {
|
|
85
85
|
setColorValue(newColor);
|
|
86
86
|
return;
|
|
@@ -111,7 +111,11 @@ export function useColorFieldState(
|
|
|
111
111
|
// Set to empty state if input value is empty
|
|
112
112
|
if (!inputValue.length) {
|
|
113
113
|
safelySetColorValue(null);
|
|
114
|
-
|
|
114
|
+
if (value === undefined || colorValue === null) {
|
|
115
|
+
setInputValue('');
|
|
116
|
+
} else {
|
|
117
|
+
setInputValue(colorValue.toString('hex'));
|
|
118
|
+
}
|
|
115
119
|
return;
|
|
116
120
|
}
|
|
117
121
|
|
|
@@ -43,12 +43,20 @@ export function useColorSliderState(props: ColorSliderStateOptions): ColorSlider
|
|
|
43
43
|
throw new Error('useColorSliderState requires a value or defaultValue');
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
if (value) {
|
|
47
|
+
value = normalizeColor(value);
|
|
48
|
+
}
|
|
49
|
+
if (defaultValue) {
|
|
50
|
+
defaultValue = normalizeColor(defaultValue);
|
|
51
|
+
}
|
|
52
|
+
// safe to cast value and defaultValue to Color, one of them will always be defined because if neither are, we throw an error
|
|
53
|
+
let [colorValue, setColor] = useControlledState<Color>(value as Color, defaultValue as Color, onChange);
|
|
47
54
|
let color = useMemo(() => colorSpace && colorValue ? colorValue.toFormat(colorSpace) : colorValue, [colorValue, colorSpace]);
|
|
48
55
|
let sliderState = useSliderState({
|
|
49
56
|
...color.getChannelRange(channel),
|
|
50
57
|
...otherProps,
|
|
51
|
-
// Unused except in getThumbValueLabel, which is overridden below. null to
|
|
58
|
+
// Unused except in getThumbValueLabel, which is overridden below. null to localize the TypeScript error for ignoring.
|
|
59
|
+
// @ts-ignore
|
|
52
60
|
numberFormatter: null,
|
|
53
61
|
value: color.getChannelValue(channel),
|
|
54
62
|
onChange(v) {
|
|
@@ -96,13 +96,20 @@ function cartesianToAngle(x: number, y: number, radius: number): number {
|
|
|
96
96
|
* Color wheels allow users to adjust the hue of an HSL or HSB color value on a circular track.
|
|
97
97
|
*/
|
|
98
98
|
export function useColorWheelState(props: ColorWheelProps): ColorWheelState {
|
|
99
|
-
let {defaultValue, onChange, onChangeEnd} = props;
|
|
99
|
+
let {value: propsValue, defaultValue, onChange, onChangeEnd} = props;
|
|
100
100
|
|
|
101
|
-
if (!
|
|
101
|
+
if (!propsValue && !defaultValue) {
|
|
102
102
|
defaultValue = DEFAULT_COLOR;
|
|
103
103
|
}
|
|
104
|
+
if (propsValue) {
|
|
105
|
+
propsValue = normalizeColor(propsValue);
|
|
106
|
+
}
|
|
107
|
+
if (defaultValue) {
|
|
108
|
+
defaultValue = normalizeColor(defaultValue);
|
|
109
|
+
}
|
|
104
110
|
|
|
105
|
-
|
|
111
|
+
// safe to cast value and defaultValue to Color, one of them will always be defined because if neither are, we assign a default
|
|
112
|
+
let [stateValue, setValueState] = useControlledState<Color>(propsValue as Color, defaultValue as Color, onChange);
|
|
106
113
|
let value = useMemo(() => {
|
|
107
114
|
let colorSpace = stateValue.getColorSpace();
|
|
108
115
|
return colorSpace === 'hsl' || colorSpace === 'hsb' ? stateValue : stateValue.toFormat('hsl');
|