@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-stately/color",
3
- "version": "3.6.2-nightly.4664+10bac541a",
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.4664+10bac541a",
26
- "@internationalized/string": "3.2.4-nightly.4664+10bac541a",
27
- "@react-aria/i18n": "3.0.0-nightly.2952+10bac541a",
28
- "@react-stately/form": "3.0.4-nightly.4664+10bac541a",
29
- "@react-stately/numberfield": "3.0.0-nightly.2952+10bac541a",
30
- "@react-stately/slider": "3.5.5-nightly.4664+10bac541a",
31
- "@react-stately/utils": "3.0.0-nightly.2952+10bac541a",
32
- "@react-types/color": "3.0.0-nightly.4664+10bac541a",
33
- "@react-types/shared": "3.0.0-nightly.2952+10bac541a",
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": "10bac541a2a5c666b443fe70f313455a405a5c77"
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) => clamp(num, 0, i < 3 ? 255 : 1));
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 | void;
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 | void;
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));
@@ -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
- let [colorValue, setColorState] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
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, initialDefaultValue, onChange);
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
- setInputValue(value === undefined ? '' : colorValue.toString('hex'));
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
- let [colorValue, setColor] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
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 appease TypeScript.
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 (!props.value && !defaultValue) {
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
- let [stateValue, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);
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');