@react-stately/color 3.5.4-nightly.4569 → 3.5.4-nightly.4578

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 (45) hide show
  1. package/dist/Color.main.js +37 -34
  2. package/dist/Color.main.js.map +1 -1
  3. package/dist/Color.mjs +37 -35
  4. package/dist/Color.module.js +37 -35
  5. package/dist/Color.module.js.map +1 -1
  6. package/dist/import.mjs +6 -2
  7. package/dist/main.js +7 -0
  8. package/dist/main.js.map +1 -1
  9. package/dist/module.js +6 -2
  10. package/dist/module.js.map +1 -1
  11. package/dist/types.d.ts +33 -1
  12. package/dist/types.d.ts.map +1 -1
  13. package/dist/useColorAreaState.main.js +6 -2
  14. package/dist/useColorAreaState.main.js.map +1 -1
  15. package/dist/useColorAreaState.mjs +7 -3
  16. package/dist/useColorAreaState.module.js +7 -3
  17. package/dist/useColorAreaState.module.js.map +1 -1
  18. package/dist/useColorChannelFieldState.main.js +48 -0
  19. package/dist/useColorChannelFieldState.main.js.map +1 -0
  20. package/dist/useColorChannelFieldState.mjs +43 -0
  21. package/dist/useColorChannelFieldState.module.js +43 -0
  22. package/dist/useColorChannelFieldState.module.js.map +1 -0
  23. package/dist/useColorPickerState.main.js +27 -0
  24. package/dist/useColorPickerState.main.js.map +1 -0
  25. package/dist/useColorPickerState.mjs +22 -0
  26. package/dist/useColorPickerState.module.js +22 -0
  27. package/dist/useColorPickerState.module.js.map +1 -0
  28. package/dist/useColorSliderState.main.js +10 -3
  29. package/dist/useColorSliderState.main.js.map +1 -1
  30. package/dist/useColorSliderState.mjs +10 -3
  31. package/dist/useColorSliderState.module.js +10 -3
  32. package/dist/useColorSliderState.module.js.map +1 -1
  33. package/dist/useColorWheelState.main.js +9 -2
  34. package/dist/useColorWheelState.main.js.map +1 -1
  35. package/dist/useColorWheelState.mjs +10 -3
  36. package/dist/useColorWheelState.module.js +10 -3
  37. package/dist/useColorWheelState.module.js.map +1 -1
  38. package/package.json +11 -9
  39. package/src/Color.ts +55 -38
  40. package/src/index.ts +5 -1
  41. package/src/useColorAreaState.ts +3 -1
  42. package/src/useColorChannelFieldState.ts +49 -0
  43. package/src/useColorPickerState.ts +27 -0
  44. package/src/useColorSliderState.ts +9 -4
  45. package/src/useColorWheelState.ts +12 -4
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/color/src/useColorWheelState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Color, ColorWheelProps} from '@react-types/color';\nimport {normalizeColor, parseColor} from './Color';\nimport {useControlledState} from '@react-stately/utils';\nimport {useRef, useState} from 'react';\n\nexport interface ColorWheelState {\n /** The current color value represented by the color wheel. */\n readonly value: Color,\n /** Sets the color value represented by the color wheel, and triggers `onChange`. */\n setValue(value: string | Color): void,\n\n /** The current value of the hue channel displayed by the color wheel. */\n readonly hue: number,\n /** Sets the hue channel of the current color value and triggers `onChange`. */\n setHue(value: number): void,\n\n /** Sets the hue channel of the current color value based on the given coordinates and radius of the color wheel, and triggers `onChange`. */\n setHueFromPoint(x: number, y: number, radius: number): void,\n /** Returns the coordinates of the thumb relative to the center point of the color wheel. */\n getThumbPosition(radius: number): {x: number, y: number},\n\n /** Increments the hue by the given amount (defaults to 1). */\n increment(stepSize?: number): void,\n /** Decrements the hue by the given amount (defaults to 1). */\n decrement(stepSize?: number): void,\n\n /** Whether the color wheel is currently being dragged. */\n readonly isDragging: boolean,\n /** Sets whether the color wheel is being dragged. */\n setDragging(value: boolean): void,\n /** Returns the color that should be displayed in the color wheel instead of `value`. */\n getDisplayColor(): Color,\n /** The step value of the hue channel, used when incrementing and decrementing. */\n step: number,\n /** The page step value of the hue channel, used when incrementing and decrementing. */\n pageStep: number\n}\n\nconst DEFAULT_COLOR = parseColor('hsl(0, 100%, 50%)');\n\nfunction roundToStep(value: number, step: number): number {\n return Math.round(value / step) * step;\n}\n\nfunction mod(n: number, m: number) {\n return ((n % m) + m) % m;\n}\n\nfunction roundDown(v: number) {\n let r = Math.floor(v);\n if (r === v) {\n return v - 1;\n } else {\n return r;\n }\n}\n\nfunction degToRad(deg: number) {\n return deg * Math.PI / 180;\n}\n\nfunction radToDeg(rad: number) {\n return rad * 180 / Math.PI;\n}\n\n// 0deg = 3 o'clock. increases clockwise\nfunction angleToCartesian(angle: number, radius: number): {x: number, y: number} {\n let rad = degToRad(360 - angle + 90);\n let x = Math.sin(rad) * (radius);\n let y = Math.cos(rad) * (radius);\n return {x, y};\n}\n\nfunction cartesianToAngle(x: number, y: number, radius: number): number {\n let deg = radToDeg(Math.atan2(y / radius, x / radius));\n return (deg + 360) % 360;\n}\n\n/**\n * Provides state management for a color wheel component.\n * Color wheels allow users to adjust the hue of an HSL or HSB color value on a circular track.\n */\nexport function useColorWheelState(props: ColorWheelProps): ColorWheelState {\n let {defaultValue, onChange, onChangeEnd} = props;\n\n if (!props.value && !defaultValue) {\n defaultValue = DEFAULT_COLOR;\n }\n\n let [value, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);\n let valueRef = useRef(value);\n let setValue = (value: Color) => {\n valueRef.current = value;\n setValueState(value);\n };\n\n let channelRange = value.getChannelRange('hue');\n let {minValue: minValueX, maxValue: maxValueX, step: step, pageSize: pageStep} = channelRange;\n let [isDragging, setDragging] = useState(false);\n let isDraggingRef = useRef(false);\n\n let hue = value.getChannelValue('hue');\n function setHue(v: number) {\n if (v > 360) {\n // Make sure you can always get back to 0.\n v = 0;\n }\n v = roundToStep(mod(v, 360), step);\n if (hue !== v) {\n let color = value.withChannelValue('hue', v);\n setValue(color);\n }\n }\n\n return {\n value,\n step,\n pageStep,\n setValue(v) {\n let color = normalizeColor(v);\n setValue(color);\n },\n hue,\n setHue,\n setHueFromPoint(x, y, radius) {\n setHue(cartesianToAngle(x, y, radius));\n },\n getThumbPosition(radius) {\n return angleToCartesian(value.getChannelValue('hue'), radius);\n },\n increment(stepSize = 1) {\n let s = Math.max(stepSize, step);\n let newValue = hue + s;\n if (newValue >= maxValueX) {\n // Make sure you can always get back to 0.\n newValue = minValueX;\n }\n setHue(roundToStep(mod(newValue, 360), s));\n },\n decrement(stepSize = 1) {\n let s = Math.max(stepSize, step);\n if (hue === 0) {\n // We can't just subtract step because this might be the case:\n // |(previous step) - 0| < step size\n setHue(roundDown(360 / s) * s);\n } else {\n setHue(roundToStep(mod(hue - s, 360), s));\n }\n },\n setDragging(isDragging) {\n let wasDragging = isDraggingRef.current;\n isDraggingRef.current = isDragging;\n\n if (onChangeEnd && !isDragging && wasDragging) {\n onChangeEnd(valueRef.current);\n }\n\n setDragging(isDragging);\n },\n isDragging,\n getDisplayColor() {\n return value.toFormat('hsl').withChannelValue('saturation', 100).withChannelValue('lightness', 50).withChannelValue('alpha', 1);\n }\n };\n}\n"],"names":[],"version":3,"file":"useColorWheelState.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-stately/color/src/useColorWheelState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Color, ColorWheelProps} from '@react-types/color';\nimport {normalizeColor, parseColor} from './Color';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMemo, useRef, useState} from 'react';\n\nexport interface ColorWheelState {\n /** The current color value represented by the color wheel. */\n readonly value: Color,\n /** Sets the color value represented by the color wheel, and triggers `onChange`. */\n setValue(value: string | Color): void,\n\n /** The current value of the hue channel displayed by the color wheel. */\n readonly hue: number,\n /** Sets the hue channel of the current color value and triggers `onChange`. */\n setHue(value: number): void,\n\n /** Sets the hue channel of the current color value based on the given coordinates and radius of the color wheel, and triggers `onChange`. */\n setHueFromPoint(x: number, y: number, radius: number): void,\n /** Returns the coordinates of the thumb relative to the center point of the color wheel. */\n getThumbPosition(radius: number): {x: number, y: number},\n\n /** Increments the hue by the given amount (defaults to 1). */\n increment(stepSize?: number): void,\n /** Decrements the hue by the given amount (defaults to 1). */\n decrement(stepSize?: number): void,\n\n /** Whether the color wheel is currently being dragged. */\n readonly isDragging: boolean,\n /** Sets whether the color wheel is being dragged. */\n setDragging(value: boolean): void,\n /** Returns the color that should be displayed in the color wheel instead of `value`. */\n getDisplayColor(): Color,\n /** The step value of the hue channel, used when incrementing and decrementing. */\n step: number,\n /** The page step value of the hue channel, used when incrementing and decrementing. */\n pageStep: number,\n\n /** Whether the color wheel is disabled. */\n readonly isDisabled: boolean\n}\n\nconst DEFAULT_COLOR = parseColor('hsl(0, 100%, 50%)');\n\nfunction roundToStep(value: number, step: number): number {\n return Math.round(value / step) * step;\n}\n\nfunction mod(n: number, m: number) {\n return ((n % m) + m) % m;\n}\n\nfunction roundDown(v: number) {\n let r = Math.floor(v);\n if (r === v) {\n return v - 1;\n } else {\n return r;\n }\n}\n\nfunction degToRad(deg: number) {\n return deg * Math.PI / 180;\n}\n\nfunction radToDeg(rad: number) {\n return rad * 180 / Math.PI;\n}\n\n// 0deg = 3 o'clock. increases clockwise\nfunction angleToCartesian(angle: number, radius: number): {x: number, y: number} {\n let rad = degToRad(360 - angle + 90);\n let x = Math.sin(rad) * (radius);\n let y = Math.cos(rad) * (radius);\n return {x, y};\n}\n\nfunction cartesianToAngle(x: number, y: number, radius: number): number {\n let deg = radToDeg(Math.atan2(y / radius, x / radius));\n return (deg + 360) % 360;\n}\n\n/**\n * Provides state management for a color wheel component.\n * Color wheels allow users to adjust the hue of an HSL or HSB color value on a circular track.\n */\nexport function useColorWheelState(props: ColorWheelProps): ColorWheelState {\n let {defaultValue, onChange, onChangeEnd} = props;\n\n if (!props.value && !defaultValue) {\n defaultValue = DEFAULT_COLOR;\n }\n\n let [stateValue, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);\n let value = useMemo(() => {\n let colorSpace = stateValue.getColorSpace();\n return colorSpace === 'hsl' || colorSpace === 'hsb' ? stateValue : stateValue.toFormat('hsl');\n }, [stateValue]);\n let valueRef = useRef(value);\n let setValue = (value: Color) => {\n valueRef.current = value;\n setValueState(value);\n };\n\n let channelRange = value.getChannelRange('hue');\n let {minValue: minValueX, maxValue: maxValueX, step: step, pageSize: pageStep} = channelRange;\n let [isDragging, setDragging] = useState(false);\n let isDraggingRef = useRef(false);\n\n let hue = value.getChannelValue('hue');\n function setHue(v: number) {\n if (v > 360) {\n // Make sure you can always get back to 0.\n v = 0;\n }\n v = roundToStep(mod(v, 360), step);\n if (hue !== v) {\n let color = value.withChannelValue('hue', v);\n setValue(color);\n }\n }\n\n return {\n value,\n step,\n pageStep,\n setValue(v) {\n let color = normalizeColor(v);\n setValue(color);\n },\n hue,\n setHue,\n setHueFromPoint(x, y, radius) {\n setHue(cartesianToAngle(x, y, radius));\n },\n getThumbPosition(radius) {\n return angleToCartesian(value.getChannelValue('hue'), radius);\n },\n increment(stepSize = 1) {\n let s = Math.max(stepSize, step);\n let newValue = hue + s;\n if (newValue >= maxValueX) {\n // Make sure you can always get back to 0.\n newValue = minValueX;\n }\n setHue(roundToStep(mod(newValue, 360), s));\n },\n decrement(stepSize = 1) {\n let s = Math.max(stepSize, step);\n if (hue === 0) {\n // We can't just subtract step because this might be the case:\n // |(previous step) - 0| < step size\n setHue(roundDown(360 / s) * s);\n } else {\n setHue(roundToStep(mod(hue - s, 360), s));\n }\n },\n setDragging(isDragging) {\n let wasDragging = isDraggingRef.current;\n isDraggingRef.current = isDragging;\n\n if (onChangeEnd && !isDragging && wasDragging) {\n onChangeEnd(valueRef.current);\n }\n\n setDragging(isDragging);\n },\n isDragging,\n getDisplayColor() {\n return value.toFormat('hsl').withChannelValue('saturation', 100).withChannelValue('lightness', 50).withChannelValue('alpha', 1);\n },\n isDisabled: props.isDisabled || false\n };\n}\n"],"names":[],"version":3,"file":"useColorWheelState.main.js.map"}
@@ -1,6 +1,6 @@
1
1
  import {normalizeColor as $799cddbef784668f$export$4cde5df63f53f473, parseColor as $799cddbef784668f$export$6e865ea70d7724f} from "./Color.mjs";
2
2
  import {useControlledState as $d4Pfi$useControlledState} from "@react-stately/utils";
3
- import {useRef as $d4Pfi$useRef, useState as $d4Pfi$useState} from "react";
3
+ import {useMemo as $d4Pfi$useMemo, useRef as $d4Pfi$useRef, useState as $d4Pfi$useState} from "react";
4
4
 
5
5
  /*
6
6
  * Copyright 2020 Adobe. All rights reserved.
@@ -50,7 +50,13 @@ function $ee4262c74a467b07$var$cartesianToAngle(x, y, radius) {
50
50
  function $ee4262c74a467b07$export$f4301076d9336137(props) {
51
51
  let { defaultValue: defaultValue, onChange: onChange, onChangeEnd: onChangeEnd } = props;
52
52
  if (!props.value && !defaultValue) defaultValue = $ee4262c74a467b07$var$DEFAULT_COLOR;
53
- let [value, setValueState] = (0, $d4Pfi$useControlledState)((0, $799cddbef784668f$export$4cde5df63f53f473)(props.value), (0, $799cddbef784668f$export$4cde5df63f53f473)(defaultValue), onChange);
53
+ let [stateValue, setValueState] = (0, $d4Pfi$useControlledState)((0, $799cddbef784668f$export$4cde5df63f53f473)(props.value), (0, $799cddbef784668f$export$4cde5df63f53f473)(defaultValue), onChange);
54
+ let value = (0, $d4Pfi$useMemo)(()=>{
55
+ let colorSpace = stateValue.getColorSpace();
56
+ return colorSpace === "hsl" || colorSpace === "hsb" ? stateValue : stateValue.toFormat("hsl");
57
+ }, [
58
+ stateValue
59
+ ]);
54
60
  let valueRef = (0, $d4Pfi$useRef)(value);
55
61
  let setValue = (value)=>{
56
62
  valueRef.current = value;
@@ -109,7 +115,8 @@ function $ee4262c74a467b07$export$f4301076d9336137(props) {
109
115
  isDragging: isDragging,
110
116
  getDisplayColor () {
111
117
  return value.toFormat("hsl").withChannelValue("saturation", 100).withChannelValue("lightness", 50).withChannelValue("alpha", 1);
112
- }
118
+ },
119
+ isDisabled: props.isDisabled || false
113
120
  };
114
121
  }
115
122
 
@@ -1,6 +1,6 @@
1
1
  import {normalizeColor as $799cddbef784668f$export$4cde5df63f53f473, parseColor as $799cddbef784668f$export$6e865ea70d7724f} from "./Color.module.js";
2
2
  import {useControlledState as $d4Pfi$useControlledState} from "@react-stately/utils";
3
- import {useRef as $d4Pfi$useRef, useState as $d4Pfi$useState} from "react";
3
+ import {useMemo as $d4Pfi$useMemo, useRef as $d4Pfi$useRef, useState as $d4Pfi$useState} from "react";
4
4
 
5
5
  /*
6
6
  * Copyright 2020 Adobe. All rights reserved.
@@ -50,7 +50,13 @@ function $ee4262c74a467b07$var$cartesianToAngle(x, y, radius) {
50
50
  function $ee4262c74a467b07$export$f4301076d9336137(props) {
51
51
  let { defaultValue: defaultValue, onChange: onChange, onChangeEnd: onChangeEnd } = props;
52
52
  if (!props.value && !defaultValue) defaultValue = $ee4262c74a467b07$var$DEFAULT_COLOR;
53
- let [value, setValueState] = (0, $d4Pfi$useControlledState)((0, $799cddbef784668f$export$4cde5df63f53f473)(props.value), (0, $799cddbef784668f$export$4cde5df63f53f473)(defaultValue), onChange);
53
+ let [stateValue, setValueState] = (0, $d4Pfi$useControlledState)((0, $799cddbef784668f$export$4cde5df63f53f473)(props.value), (0, $799cddbef784668f$export$4cde5df63f53f473)(defaultValue), onChange);
54
+ let value = (0, $d4Pfi$useMemo)(()=>{
55
+ let colorSpace = stateValue.getColorSpace();
56
+ return colorSpace === "hsl" || colorSpace === "hsb" ? stateValue : stateValue.toFormat("hsl");
57
+ }, [
58
+ stateValue
59
+ ]);
54
60
  let valueRef = (0, $d4Pfi$useRef)(value);
55
61
  let setValue = (value)=>{
56
62
  valueRef.current = value;
@@ -109,7 +115,8 @@ function $ee4262c74a467b07$export$f4301076d9336137(props) {
109
115
  isDragging: isDragging,
110
116
  getDisplayColor () {
111
117
  return value.toFormat("hsl").withChannelValue("saturation", 100).withChannelValue("lightness", 50).withChannelValue("alpha", 1);
112
- }
118
+ },
119
+ isDisabled: props.isDisabled || false
113
120
  };
114
121
  }
115
122
 
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/color/src/useColorWheelState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Color, ColorWheelProps} from '@react-types/color';\nimport {normalizeColor, parseColor} from './Color';\nimport {useControlledState} from '@react-stately/utils';\nimport {useRef, useState} from 'react';\n\nexport interface ColorWheelState {\n /** The current color value represented by the color wheel. */\n readonly value: Color,\n /** Sets the color value represented by the color wheel, and triggers `onChange`. */\n setValue(value: string | Color): void,\n\n /** The current value of the hue channel displayed by the color wheel. */\n readonly hue: number,\n /** Sets the hue channel of the current color value and triggers `onChange`. */\n setHue(value: number): void,\n\n /** Sets the hue channel of the current color value based on the given coordinates and radius of the color wheel, and triggers `onChange`. */\n setHueFromPoint(x: number, y: number, radius: number): void,\n /** Returns the coordinates of the thumb relative to the center point of the color wheel. */\n getThumbPosition(radius: number): {x: number, y: number},\n\n /** Increments the hue by the given amount (defaults to 1). */\n increment(stepSize?: number): void,\n /** Decrements the hue by the given amount (defaults to 1). */\n decrement(stepSize?: number): void,\n\n /** Whether the color wheel is currently being dragged. */\n readonly isDragging: boolean,\n /** Sets whether the color wheel is being dragged. */\n setDragging(value: boolean): void,\n /** Returns the color that should be displayed in the color wheel instead of `value`. */\n getDisplayColor(): Color,\n /** The step value of the hue channel, used when incrementing and decrementing. */\n step: number,\n /** The page step value of the hue channel, used when incrementing and decrementing. */\n pageStep: number\n}\n\nconst DEFAULT_COLOR = parseColor('hsl(0, 100%, 50%)');\n\nfunction roundToStep(value: number, step: number): number {\n return Math.round(value / step) * step;\n}\n\nfunction mod(n: number, m: number) {\n return ((n % m) + m) % m;\n}\n\nfunction roundDown(v: number) {\n let r = Math.floor(v);\n if (r === v) {\n return v - 1;\n } else {\n return r;\n }\n}\n\nfunction degToRad(deg: number) {\n return deg * Math.PI / 180;\n}\n\nfunction radToDeg(rad: number) {\n return rad * 180 / Math.PI;\n}\n\n// 0deg = 3 o'clock. increases clockwise\nfunction angleToCartesian(angle: number, radius: number): {x: number, y: number} {\n let rad = degToRad(360 - angle + 90);\n let x = Math.sin(rad) * (radius);\n let y = Math.cos(rad) * (radius);\n return {x, y};\n}\n\nfunction cartesianToAngle(x: number, y: number, radius: number): number {\n let deg = radToDeg(Math.atan2(y / radius, x / radius));\n return (deg + 360) % 360;\n}\n\n/**\n * Provides state management for a color wheel component.\n * Color wheels allow users to adjust the hue of an HSL or HSB color value on a circular track.\n */\nexport function useColorWheelState(props: ColorWheelProps): ColorWheelState {\n let {defaultValue, onChange, onChangeEnd} = props;\n\n if (!props.value && !defaultValue) {\n defaultValue = DEFAULT_COLOR;\n }\n\n let [value, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);\n let valueRef = useRef(value);\n let setValue = (value: Color) => {\n valueRef.current = value;\n setValueState(value);\n };\n\n let channelRange = value.getChannelRange('hue');\n let {minValue: minValueX, maxValue: maxValueX, step: step, pageSize: pageStep} = channelRange;\n let [isDragging, setDragging] = useState(false);\n let isDraggingRef = useRef(false);\n\n let hue = value.getChannelValue('hue');\n function setHue(v: number) {\n if (v > 360) {\n // Make sure you can always get back to 0.\n v = 0;\n }\n v = roundToStep(mod(v, 360), step);\n if (hue !== v) {\n let color = value.withChannelValue('hue', v);\n setValue(color);\n }\n }\n\n return {\n value,\n step,\n pageStep,\n setValue(v) {\n let color = normalizeColor(v);\n setValue(color);\n },\n hue,\n setHue,\n setHueFromPoint(x, y, radius) {\n setHue(cartesianToAngle(x, y, radius));\n },\n getThumbPosition(radius) {\n return angleToCartesian(value.getChannelValue('hue'), radius);\n },\n increment(stepSize = 1) {\n let s = Math.max(stepSize, step);\n let newValue = hue + s;\n if (newValue >= maxValueX) {\n // Make sure you can always get back to 0.\n newValue = minValueX;\n }\n setHue(roundToStep(mod(newValue, 360), s));\n },\n decrement(stepSize = 1) {\n let s = Math.max(stepSize, step);\n if (hue === 0) {\n // We can't just subtract step because this might be the case:\n // |(previous step) - 0| < step size\n setHue(roundDown(360 / s) * s);\n } else {\n setHue(roundToStep(mod(hue - s, 360), s));\n }\n },\n setDragging(isDragging) {\n let wasDragging = isDraggingRef.current;\n isDraggingRef.current = isDragging;\n\n if (onChangeEnd && !isDragging && wasDragging) {\n onChangeEnd(valueRef.current);\n }\n\n setDragging(isDragging);\n },\n isDragging,\n getDisplayColor() {\n return value.toFormat('hsl').withChannelValue('saturation', 100).withChannelValue('lightness', 50).withChannelValue('alpha', 1);\n }\n };\n}\n"],"names":[],"version":3,"file":"useColorWheelState.module.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-stately/color/src/useColorWheelState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Color, ColorWheelProps} from '@react-types/color';\nimport {normalizeColor, parseColor} from './Color';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMemo, useRef, useState} from 'react';\n\nexport interface ColorWheelState {\n /** The current color value represented by the color wheel. */\n readonly value: Color,\n /** Sets the color value represented by the color wheel, and triggers `onChange`. */\n setValue(value: string | Color): void,\n\n /** The current value of the hue channel displayed by the color wheel. */\n readonly hue: number,\n /** Sets the hue channel of the current color value and triggers `onChange`. */\n setHue(value: number): void,\n\n /** Sets the hue channel of the current color value based on the given coordinates and radius of the color wheel, and triggers `onChange`. */\n setHueFromPoint(x: number, y: number, radius: number): void,\n /** Returns the coordinates of the thumb relative to the center point of the color wheel. */\n getThumbPosition(radius: number): {x: number, y: number},\n\n /** Increments the hue by the given amount (defaults to 1). */\n increment(stepSize?: number): void,\n /** Decrements the hue by the given amount (defaults to 1). */\n decrement(stepSize?: number): void,\n\n /** Whether the color wheel is currently being dragged. */\n readonly isDragging: boolean,\n /** Sets whether the color wheel is being dragged. */\n setDragging(value: boolean): void,\n /** Returns the color that should be displayed in the color wheel instead of `value`. */\n getDisplayColor(): Color,\n /** The step value of the hue channel, used when incrementing and decrementing. */\n step: number,\n /** The page step value of the hue channel, used when incrementing and decrementing. */\n pageStep: number,\n\n /** Whether the color wheel is disabled. */\n readonly isDisabled: boolean\n}\n\nconst DEFAULT_COLOR = parseColor('hsl(0, 100%, 50%)');\n\nfunction roundToStep(value: number, step: number): number {\n return Math.round(value / step) * step;\n}\n\nfunction mod(n: number, m: number) {\n return ((n % m) + m) % m;\n}\n\nfunction roundDown(v: number) {\n let r = Math.floor(v);\n if (r === v) {\n return v - 1;\n } else {\n return r;\n }\n}\n\nfunction degToRad(deg: number) {\n return deg * Math.PI / 180;\n}\n\nfunction radToDeg(rad: number) {\n return rad * 180 / Math.PI;\n}\n\n// 0deg = 3 o'clock. increases clockwise\nfunction angleToCartesian(angle: number, radius: number): {x: number, y: number} {\n let rad = degToRad(360 - angle + 90);\n let x = Math.sin(rad) * (radius);\n let y = Math.cos(rad) * (radius);\n return {x, y};\n}\n\nfunction cartesianToAngle(x: number, y: number, radius: number): number {\n let deg = radToDeg(Math.atan2(y / radius, x / radius));\n return (deg + 360) % 360;\n}\n\n/**\n * Provides state management for a color wheel component.\n * Color wheels allow users to adjust the hue of an HSL or HSB color value on a circular track.\n */\nexport function useColorWheelState(props: ColorWheelProps): ColorWheelState {\n let {defaultValue, onChange, onChangeEnd} = props;\n\n if (!props.value && !defaultValue) {\n defaultValue = DEFAULT_COLOR;\n }\n\n let [stateValue, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);\n let value = useMemo(() => {\n let colorSpace = stateValue.getColorSpace();\n return colorSpace === 'hsl' || colorSpace === 'hsb' ? stateValue : stateValue.toFormat('hsl');\n }, [stateValue]);\n let valueRef = useRef(value);\n let setValue = (value: Color) => {\n valueRef.current = value;\n setValueState(value);\n };\n\n let channelRange = value.getChannelRange('hue');\n let {minValue: minValueX, maxValue: maxValueX, step: step, pageSize: pageStep} = channelRange;\n let [isDragging, setDragging] = useState(false);\n let isDraggingRef = useRef(false);\n\n let hue = value.getChannelValue('hue');\n function setHue(v: number) {\n if (v > 360) {\n // Make sure you can always get back to 0.\n v = 0;\n }\n v = roundToStep(mod(v, 360), step);\n if (hue !== v) {\n let color = value.withChannelValue('hue', v);\n setValue(color);\n }\n }\n\n return {\n value,\n step,\n pageStep,\n setValue(v) {\n let color = normalizeColor(v);\n setValue(color);\n },\n hue,\n setHue,\n setHueFromPoint(x, y, radius) {\n setHue(cartesianToAngle(x, y, radius));\n },\n getThumbPosition(radius) {\n return angleToCartesian(value.getChannelValue('hue'), radius);\n },\n increment(stepSize = 1) {\n let s = Math.max(stepSize, step);\n let newValue = hue + s;\n if (newValue >= maxValueX) {\n // Make sure you can always get back to 0.\n newValue = minValueX;\n }\n setHue(roundToStep(mod(newValue, 360), s));\n },\n decrement(stepSize = 1) {\n let s = Math.max(stepSize, step);\n if (hue === 0) {\n // We can't just subtract step because this might be the case:\n // |(previous step) - 0| < step size\n setHue(roundDown(360 / s) * s);\n } else {\n setHue(roundToStep(mod(hue - s, 360), s));\n }\n },\n setDragging(isDragging) {\n let wasDragging = isDraggingRef.current;\n isDraggingRef.current = isDragging;\n\n if (onChangeEnd && !isDragging && wasDragging) {\n onChangeEnd(valueRef.current);\n }\n\n setDragging(isDragging);\n },\n isDragging,\n getDisplayColor() {\n return value.toFormat('hsl').withChannelValue('saturation', 100).withChannelValue('lightness', 50).withChannelValue('alpha', 1);\n },\n isDisabled: props.isDisabled || false\n };\n}\n"],"names":[],"version":3,"file":"useColorWheelState.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-stately/color",
3
- "version": "3.5.4-nightly.4569+1550ccaa6",
3
+ "version": "3.5.4-nightly.4578+b09a14eb1",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -22,13 +22,15 @@
22
22
  "url": "https://github.com/adobe/react-spectrum"
23
23
  },
24
24
  "dependencies": {
25
- "@internationalized/number": "3.5.2-nightly.4569+1550ccaa6",
26
- "@internationalized/string": "3.2.2-nightly.4569+1550ccaa6",
27
- "@react-aria/i18n": "3.0.0-nightly.2857+1550ccaa6",
28
- "@react-stately/form": "3.0.2-nightly.4569+1550ccaa6",
29
- "@react-stately/slider": "3.5.3-nightly.4569+1550ccaa6",
30
- "@react-stately/utils": "3.0.0-nightly.2857+1550ccaa6",
31
- "@react-types/color": "3.0.0-nightly.4569+1550ccaa6",
25
+ "@internationalized/number": "3.5.2-nightly.4578+b09a14eb1",
26
+ "@internationalized/string": "3.2.2-nightly.4578+b09a14eb1",
27
+ "@react-aria/i18n": "3.0.0-nightly.2866+b09a14eb1",
28
+ "@react-stately/form": "3.0.2-nightly.4578+b09a14eb1",
29
+ "@react-stately/numberfield": "3.0.0-nightly.2866+b09a14eb1",
30
+ "@react-stately/slider": "3.5.3-nightly.4578+b09a14eb1",
31
+ "@react-stately/utils": "3.0.0-nightly.2866+b09a14eb1",
32
+ "@react-types/color": "3.0.0-nightly.4578+b09a14eb1",
33
+ "@react-types/shared": "3.0.0-nightly.2866+b09a14eb1",
32
34
  "@swc/helpers": "^0.5.0"
33
35
  },
34
36
  "peerDependencies": {
@@ -37,5 +39,5 @@
37
39
  "publishConfig": {
38
40
  "access": "public"
39
41
  },
40
- "gitHead": "1550ccaa62363b65079eb2e36563380db0e7c043"
42
+ "gitHead": "b09a14eb1854d9d52e08739e30aa8fae51f1595a"
41
43
  }
package/src/Color.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import {clamp, toFixedNumber} from '@react-stately/utils';
14
- import {ColorAxes, ColorChannel, ColorChannelRange, ColorFormat, Color as IColor} from '@react-types/color';
14
+ import {ColorAxes, ColorChannel, ColorChannelRange, ColorFormat, ColorSpace, Color as IColor} from '@react-types/color';
15
15
  // @ts-ignore
16
16
  import intlMessages from '../intl/*.json';
17
17
  import {LocalizedStringDictionary, LocalizedStringFormatter} from '@internationalized/string';
@@ -37,6 +37,18 @@ export function normalizeColor(v: string | IColor) {
37
37
  }
38
38
  }
39
39
 
40
+ /** Returns a list of color channels for a given color space. */
41
+ export function getColorChannels(colorSpace: ColorSpace) {
42
+ switch (colorSpace) {
43
+ case 'rgb':
44
+ return RGBColor.colorChannels;
45
+ case 'hsl':
46
+ return HSLColor.colorChannels;
47
+ case 'hsb':
48
+ return HSBColor.colorChannels;
49
+ }
50
+ }
51
+
40
52
  // Lightness threshold between orange and brown.
41
53
  const ORANGE_LIGHTNESS_THRESHOLD = 0.68;
42
54
  // Lightness threshold between pure yellow and "yellow green".
@@ -63,6 +75,7 @@ abstract class Color implements IColor {
63
75
  abstract toString(format: ColorFormat | 'css'): string;
64
76
  abstract clone(): IColor;
65
77
  abstract getChannelRange(channel: ColorChannel): ColorChannelRange;
78
+ abstract getChannelFormatOptions(channel: ColorChannel): Intl.NumberFormatOptions;
66
79
  abstract formatChannelValue(channel: ColorChannel, locale: string): string;
67
80
 
68
81
  toHexInt(): number {
@@ -92,7 +105,8 @@ abstract class Color implements IColor {
92
105
  return strings.getStringForLocale(channel, locale);
93
106
  }
94
107
 
95
- abstract getColorSpace(): ColorFormat
108
+ abstract getColorSpace(): ColorSpace;
109
+
96
110
  getColorSpaceAxes(xyChannels: {xChannel?: ColorChannel, yChannel?: ColorChannel}): ColorAxes {
97
111
  let {xChannel, yChannel} = xyChannels;
98
112
  let xCh = xChannel || this.getColorChannels().find(c => c !== yChannel);
@@ -240,7 +254,7 @@ class RGBColor extends Color {
240
254
  return colors.length < 3 ? undefined : new RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1);
241
255
  }
242
256
 
243
- toString(format: ColorFormat | 'css') {
257
+ toString(format: ColorFormat | 'css' = 'css') {
244
258
  switch (format) {
245
259
  case 'hex':
246
260
  return '#' + (this.red.toString(16).padStart(2, '0') + this.green.toString(16).padStart(2, '0') + this.blue.toString(16).padStart(2, '0')).toUpperCase();
@@ -377,29 +391,30 @@ class RGBColor extends Color {
377
391
  }
378
392
  }
379
393
 
380
- formatChannelValue(channel: ColorChannel, locale: string) {
381
- let options: Intl.NumberFormatOptions;
382
- let value = this.getChannelValue(channel);
394
+ getChannelFormatOptions(channel: ColorChannel): Intl.NumberFormatOptions {
383
395
  switch (channel) {
384
396
  case 'red':
385
397
  case 'green':
386
398
  case 'blue':
387
- options = {style: 'decimal'};
388
- break;
399
+ return {style: 'decimal'};
389
400
  case 'alpha':
390
- options = {style: 'percent'};
391
- break;
401
+ return {style: 'percent'};
392
402
  default:
393
403
  throw new Error('Unknown color channel: ' + channel);
394
404
  }
405
+ }
406
+
407
+ formatChannelValue(channel: ColorChannel, locale: string) {
408
+ let options = this.getChannelFormatOptions(channel);
409
+ let value = this.getChannelValue(channel);
395
410
  return new NumberFormatter(locale, options).format(value);
396
411
  }
397
412
 
398
- getColorSpace(): ColorFormat {
413
+ getColorSpace(): ColorSpace {
399
414
  return 'rgb';
400
415
  }
401
416
 
402
- private static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['red', 'green', 'blue'];
417
+ static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['red', 'green', 'blue'];
403
418
  getColorChannels(): [ColorChannel, ColorChannel, ColorChannel] {
404
419
  return RGBColor.colorChannels;
405
420
  }
@@ -424,7 +439,7 @@ class HSBColor extends Color {
424
439
  }
425
440
  }
426
441
 
427
- toString(format: ColorFormat | 'css') {
442
+ toString(format: ColorFormat | 'css' = 'css') {
428
443
  switch (format) {
429
444
  case 'css':
430
445
  return this.toHSL().toString('css');
@@ -512,32 +527,33 @@ class HSBColor extends Color {
512
527
  }
513
528
  }
514
529
 
515
- formatChannelValue(channel: ColorChannel, locale: string) {
516
- let options: Intl.NumberFormatOptions;
517
- let value = this.getChannelValue(channel);
530
+ getChannelFormatOptions(channel: ColorChannel): Intl.NumberFormatOptions {
518
531
  switch (channel) {
519
532
  case 'hue':
520
- options = {style: 'unit', unit: 'degree', unitDisplay: 'narrow'};
521
- break;
533
+ return {style: 'unit', unit: 'degree', unitDisplay: 'narrow'};
522
534
  case 'saturation':
523
535
  case 'brightness':
524
- options = {style: 'percent'};
525
- value /= 100;
526
- break;
527
536
  case 'alpha':
528
- options = {style: 'percent'};
529
- break;
537
+ return {style: 'percent'};
530
538
  default:
531
539
  throw new Error('Unknown color channel: ' + channel);
532
540
  }
541
+ }
542
+
543
+ formatChannelValue(channel: ColorChannel, locale: string) {
544
+ let options = this.getChannelFormatOptions(channel);
545
+ let value = this.getChannelValue(channel);
546
+ if (channel === 'saturation' || channel === 'brightness') {
547
+ value /= 100;
548
+ }
533
549
  return new NumberFormatter(locale, options).format(value);
534
550
  }
535
551
 
536
- getColorSpace(): ColorFormat {
552
+ getColorSpace(): ColorSpace {
537
553
  return 'hsb';
538
554
  }
539
555
 
540
- private static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['hue', 'saturation', 'brightness'];
556
+ static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['hue', 'saturation', 'brightness'];
541
557
  getColorChannels(): [ColorChannel, ColorChannel, ColorChannel] {
542
558
  return HSBColor.colorChannels;
543
559
  }
@@ -566,7 +582,7 @@ class HSLColor extends Color {
566
582
  }
567
583
  }
568
584
 
569
- toString(format: ColorFormat | 'css') {
585
+ toString(format: ColorFormat | 'css' = 'css') {
570
586
  switch (format) {
571
587
  case 'hex':
572
588
  return this.toRGB().toString('hex');
@@ -652,32 +668,33 @@ class HSLColor extends Color {
652
668
  }
653
669
  }
654
670
 
655
- formatChannelValue(channel: ColorChannel, locale: string) {
656
- let options: Intl.NumberFormatOptions;
657
- let value = this.getChannelValue(channel);
671
+ getChannelFormatOptions(channel: ColorChannel): Intl.NumberFormatOptions {
658
672
  switch (channel) {
659
673
  case 'hue':
660
- options = {style: 'unit', unit: 'degree', unitDisplay: 'narrow'};
661
- break;
674
+ return {style: 'unit', unit: 'degree', unitDisplay: 'narrow'};
662
675
  case 'saturation':
663
676
  case 'lightness':
664
- options = {style: 'percent'};
665
- value /= 100;
666
- break;
667
677
  case 'alpha':
668
- options = {style: 'percent'};
669
- break;
678
+ return {style: 'percent'};
670
679
  default:
671
680
  throw new Error('Unknown color channel: ' + channel);
672
681
  }
682
+ }
683
+
684
+ formatChannelValue(channel: ColorChannel, locale: string) {
685
+ let options = this.getChannelFormatOptions(channel);
686
+ let value = this.getChannelValue(channel);
687
+ if (channel === 'saturation' || channel === 'lightness') {
688
+ value /= 100;
689
+ }
673
690
  return new NumberFormatter(locale, options).format(value);
674
691
  }
675
692
 
676
- getColorSpace(): ColorFormat {
693
+ getColorSpace(): ColorSpace {
677
694
  return 'hsl';
678
695
  }
679
696
 
680
- private static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['hue', 'saturation', 'lightness'];
697
+ static colorChannels: [ColorChannel, ColorChannel, ColorChannel] = ['hue', 'saturation', 'lightness'];
681
698
  getColorChannels(): [ColorChannel, ColorChannel, ColorChannel] {
682
699
  return HSLColor.colorChannels;
683
700
  }
package/src/index.ts CHANGED
@@ -14,12 +14,16 @@ export type {ColorAreaState} from './useColorAreaState';
14
14
  export type {ColorSliderState} from './useColorSliderState';
15
15
  export type {ColorWheelState} from './useColorWheelState';
16
16
  export type {ColorFieldState} from './useColorFieldState';
17
+ export type {ColorChannelFieldProps, ColorChannelFieldState, ColorChannelFieldStateOptions} from './useColorChannelFieldState';
18
+ export type {ColorPickerProps, ColorPickerState} from './useColorPickerState';
17
19
 
18
- export {parseColor} from './Color';
20
+ export {parseColor, getColorChannels} from './Color';
19
21
  export {useColorAreaState} from './useColorAreaState';
20
22
  export {useColorSliderState} from './useColorSliderState';
21
23
  export {useColorWheelState} from './useColorWheelState';
22
24
  export {useColorFieldState} from './useColorFieldState';
25
+ export {useColorChannelFieldState} from './useColorChannelFieldState';
26
+ export {useColorPickerState} from './useColorPickerState';
23
27
 
24
28
  export type {Color, ColorAreaProps, ColorFieldProps, ColorWheelProps} from '@react-types/color';
25
29
  export type {ColorSliderStateOptions} from './useColorSliderState';
@@ -75,6 +75,7 @@ export function useColorAreaState(props: ColorAreaProps): ColorAreaState {
75
75
  let {
76
76
  value,
77
77
  defaultValue,
78
+ colorSpace,
78
79
  xChannel,
79
80
  yChannel,
80
81
  onChange,
@@ -85,7 +86,8 @@ export function useColorAreaState(props: ColorAreaProps): ColorAreaState {
85
86
  defaultValue = DEFAULT_COLOR;
86
87
  }
87
88
 
88
- let [color, setColorState] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
89
+ let [colorValue, setColorState] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
90
+ let color = useMemo(() => colorSpace && colorValue ? colorValue.toFormat(colorSpace) : colorValue, [colorValue, colorSpace]);
89
91
  let valueRef = useRef(color);
90
92
  let setColor = (color: Color) => {
91
93
  valueRef.current = color;
@@ -0,0 +1,49 @@
1
+ import {Color, ColorChannel, ColorFieldProps, ColorSpace} from '@react-types/color';
2
+ import {NumberFieldState, useNumberFieldState} from '@react-stately/numberfield';
3
+ import {useColor} from './useColor';
4
+ import {useControlledState} from '@react-stately/utils';
5
+ import {useMemo} from 'react';
6
+
7
+ export interface ColorChannelFieldProps extends ColorFieldProps {
8
+ colorSpace?: ColorSpace,
9
+ channel: ColorChannel
10
+ }
11
+
12
+ export interface ColorChannelFieldStateOptions extends ColorChannelFieldProps {
13
+ locale: string
14
+ }
15
+
16
+ export interface ColorChannelFieldState extends NumberFieldState {
17
+ colorValue: Color
18
+ }
19
+
20
+ /**
21
+ * Provides state management for a color channel field, allowing users to edit the
22
+ * value of an individual color channel.
23
+ */
24
+ export function useColorChannelFieldState(props: ColorChannelFieldStateOptions): ColorChannelFieldState {
25
+ let {channel, colorSpace, locale} = props;
26
+ let initialValue = useColor(props.value);
27
+ let initialDefaultValue = useColor(props.defaultValue || '#0000')!;
28
+ let [colorValue, setColor] = useControlledState(initialValue || undefined, initialDefaultValue, props.onChange);
29
+ let color = useMemo(() => colorSpace && colorValue ? colorValue.toFormat(colorSpace) : colorValue, [colorValue, colorSpace]);
30
+ let value = color.getChannelValue(channel);
31
+ let range = color.getChannelRange(channel);
32
+ let formatOptions = useMemo(() => color.getChannelFormatOptions(channel), [color, channel]);
33
+ let multiplier = formatOptions.style === 'percent' && range.maxValue === 100 ? 100 : 1;
34
+
35
+ let numberFieldState = useNumberFieldState({
36
+ locale,
37
+ value: value / multiplier,
38
+ onChange: (v) => setColor(color.withChannelValue(channel, v * multiplier)),
39
+ minValue: range.minValue / multiplier,
40
+ maxValue: range.maxValue / multiplier,
41
+ step: range.step / multiplier,
42
+ formatOptions
43
+ });
44
+
45
+ return {
46
+ ...numberFieldState,
47
+ colorValue: color
48
+ };
49
+ }
@@ -0,0 +1,27 @@
1
+ import {Color} from '@react-types/color';
2
+ import {parseColor} from './Color';
3
+ import {useColor} from './useColor';
4
+ import {useControlledState} from '@react-stately/utils';
5
+ import {ValueBase} from '@react-types/shared';
6
+
7
+ export interface ColorPickerProps extends ValueBase<string | Color | null, Color> {}
8
+
9
+ export interface ColorPickerState {
10
+ /** The current color value of the color picker. */
11
+ color: Color,
12
+ /** Sets the current color value of the color picker. */
13
+ setColor(color: Color | null): void
14
+ }
15
+
16
+ export function useColorPickerState(props: ColorPickerProps): ColorPickerState {
17
+ let value = useColor(props.value);
18
+ let defaultValue = useColor(props.defaultValue || '#0000')!;
19
+ let [color, setColor] = useControlledState(value || undefined, defaultValue, props.onChange);
20
+
21
+ return {
22
+ color,
23
+ setColor(color) {
24
+ setColor(color || parseColor('#0000'));
25
+ }
26
+ };
27
+ }
@@ -14,6 +14,7 @@ import {Color, ColorSliderProps} from '@react-types/color';
14
14
  import {normalizeColor, parseColor} from './Color';
15
15
  import {SliderState, useSliderState} from '@react-stately/slider';
16
16
  import {useControlledState} from '@react-stately/utils';
17
+ import {useMemo} from 'react';
17
18
 
18
19
  export interface ColorSliderState extends SliderState {
19
20
  /** The current color value represented by the color slider. */
@@ -21,7 +22,9 @@ export interface ColorSliderState extends SliderState {
21
22
  /** Sets the current color value. If a string is passed, it will be parsed to a Color. */
22
23
  setValue(value: string | Color): void,
23
24
  /** Returns the color that should be displayed in the slider instead of `value` or the optional parameter. */
24
- getDisplayColor(): Color
25
+ getDisplayColor(): Color,
26
+ /** Whether the color slider is currently being dragged. */
27
+ readonly isDragging: boolean
25
28
  }
26
29
 
27
30
 
@@ -35,12 +38,13 @@ export interface ColorSliderStateOptions extends ColorSliderProps {
35
38
  * Color sliders allow users to adjust an individual channel of a color value.
36
39
  */
37
40
  export function useColorSliderState(props: ColorSliderStateOptions): ColorSliderState {
38
- let {channel, value, defaultValue, onChange, locale, ...otherProps} = props;
41
+ let {channel, colorSpace, value, defaultValue, onChange, locale, ...otherProps} = props;
39
42
  if (value == null && defaultValue == null) {
40
43
  throw new Error('useColorSliderState requires a value or defaultValue');
41
44
  }
42
45
 
43
- let [color, setColor] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
46
+ let [colorValue, setColor] = useControlledState(value && normalizeColor(value), defaultValue && normalizeColor(defaultValue), onChange);
47
+ let color = useMemo(() => colorSpace && colorValue ? colorValue.toFormat(colorSpace) : colorValue, [colorValue, colorSpace]);
44
48
  let sliderState = useSliderState({
45
49
  ...color.getChannelRange(channel),
46
50
  ...otherProps,
@@ -87,6 +91,7 @@ export function useColorSliderState(props: ColorSliderStateOptions): ColorSlider
87
91
  return color.formatChannelValue(channel, locale);
88
92
  },
89
93
  step,
90
- pageSize
94
+ pageSize,
95
+ isDragging: sliderState.isThumbDragging(0)
91
96
  };
92
97
  }
@@ -13,7 +13,7 @@
13
13
  import {Color, ColorWheelProps} from '@react-types/color';
14
14
  import {normalizeColor, parseColor} from './Color';
15
15
  import {useControlledState} from '@react-stately/utils';
16
- import {useRef, useState} from 'react';
16
+ import {useMemo, useRef, useState} from 'react';
17
17
 
18
18
  export interface ColorWheelState {
19
19
  /** The current color value represented by the color wheel. */
@@ -45,7 +45,10 @@ export interface ColorWheelState {
45
45
  /** The step value of the hue channel, used when incrementing and decrementing. */
46
46
  step: number,
47
47
  /** The page step value of the hue channel, used when incrementing and decrementing. */
48
- pageStep: number
48
+ pageStep: number,
49
+
50
+ /** Whether the color wheel is disabled. */
51
+ readonly isDisabled: boolean
49
52
  }
50
53
 
51
54
  const DEFAULT_COLOR = parseColor('hsl(0, 100%, 50%)');
@@ -99,7 +102,11 @@ export function useColorWheelState(props: ColorWheelProps): ColorWheelState {
99
102
  defaultValue = DEFAULT_COLOR;
100
103
  }
101
104
 
102
- let [value, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);
105
+ let [stateValue, setValueState] = useControlledState(normalizeColor(props.value), normalizeColor(defaultValue), onChange);
106
+ let value = useMemo(() => {
107
+ let colorSpace = stateValue.getColorSpace();
108
+ return colorSpace === 'hsl' || colorSpace === 'hsb' ? stateValue : stateValue.toFormat('hsl');
109
+ }, [stateValue]);
103
110
  let valueRef = useRef(value);
104
111
  let setValue = (value: Color) => {
105
112
  valueRef.current = value;
@@ -172,6 +179,7 @@ export function useColorWheelState(props: ColorWheelProps): ColorWheelState {
172
179
  isDragging,
173
180
  getDisplayColor() {
174
181
  return value.toFormat('hsl').withChannelValue('saturation', 100).withChannelValue('lightness', 50).withChannelValue('alpha', 1);
175
- }
182
+ },
183
+ isDisabled: props.isDisabled || false
176
184
  };
177
185
  }