{"mappings":"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","sources":["packages/react-stately/src/color/useColorFieldState.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} from './types';\nimport {FocusableProps, HelpTextProps, InputBase, LabelableProps, TextInputBase, Validation, ValueBase} from '@react-types/shared';\nimport {FormValidationState, useFormValidationState} from '../form/useFormValidationState';\nimport {parseColor} from './Color';\nimport {useColor} from './useColor';\nimport {useControlledState} from '../utils/useControlledState';\nimport {useMemo, useState} from 'react';\n\nexport interface ColorFieldProps extends Omit<ValueBase<string | Color | null>, 'onChange'>, InputBase, Validation<Color | null>, FocusableProps, TextInputBase, LabelableProps, HelpTextProps {\n  /** Handler that is called when the value changes. */\n  onChange?: (color: Color | null) => void\n}\n\nexport interface ColorFieldState extends FormValidationState {\n  /**\n   * The current text value of the input. Updated as the user types,\n   * and formatted according to `formatOptions` on blur.\n   */\n  readonly inputValue: string,\n  /**\n   * The currently parsed color value, or null if the field is empty.\n   * Updated based on the `inputValue` as the user types.\n   */\n  readonly colorValue: Color | null,\n  /** The default value of the color field. */\n  readonly defaultColorValue: Color | null,\n  /** Sets the color value of the field. */\n  setColorValue(value: Color | null): void,\n  /** Sets the current text value of the input. */\n  setInputValue(value: string): void,\n  /**\n   * Updates the input value based on the currently parsed color value.\n   * Typically this is called when the field is blurred.\n   */\n  commit(): void,\n  /** Increments the current input value to the next step boundary, and fires `onChange`. */\n  increment(): void,\n  /** Decrements the current input value to the next step boundary, and fires `onChange`. */\n  decrement(): void,\n  /** Sets the current value to the maximum color value, and fires `onChange`. */\n  incrementToMax(): void,\n  /** Sets the current value to the minimum color value, and fires `onChange`. */\n  decrementToMin(): void,\n  /**\n   * Validates a user input string.\n   * Values can be partially entered, and may be valid even if they cannot currently be parsed to a color.\n   * Can be used to implement validation as a user types.\n   */\n  validate(value: string): boolean\n}\n\nconst MIN_COLOR = parseColor('#000000');\nconst MAX_COLOR = parseColor('#FFFFFF');\nconst MIN_COLOR_INT = MIN_COLOR.toHexInt();\nconst MAX_COLOR_INT = MAX_COLOR.toHexInt();\n\n/**\n * Provides state management for a color field component. Color fields allow\n * users to enter and adjust a hex color value.\n */\nexport function useColorFieldState(\n  props: ColorFieldProps\n): ColorFieldState {\n  let {\n    value,\n    defaultValue,\n    onChange\n  } = props;\n  let {step} = MIN_COLOR.getChannelRange('red');\n\n  let initialDefaultValue = useColor(defaultValue);\n  let [colorValue, setColorValue] = useControlledState<Color | null>(useColor(value), initialDefaultValue!, onChange);\n  let [initialValue] = useState(colorValue);\n  let [inputValue, setInputValue] = useState(() => (value || defaultValue) && colorValue ? colorValue.toString('hex') : '');\n\n  let validation = useFormValidationState({\n    ...props,\n    value: colorValue\n  });\n\n  let safelySetColorValue = (newColor: Color | null) => {\n    if (!colorValue || !newColor) {\n      setColorValue(newColor);\n      return;\n    }\n    if (newColor.toHexInt() !== colorValue.toHexInt()) {\n      setColorValue(newColor);\n      return;\n    }\n  };\n\n  let [prevValue, setPrevValue] = useState(colorValue);\n  if (prevValue !== colorValue) {\n    setInputValue(colorValue ? colorValue.toString('hex') : '');\n    setPrevValue(colorValue);\n  }\n\n  let parsedValue = useMemo(() => {\n    let color;\n    try {\n      color = parseColor(inputValue.startsWith('#') ? inputValue : `#${inputValue}`);\n    } catch {\n      color = null;\n    }\n    return color;\n  }, [inputValue]);\n\n  let commit = () => {\n    // Set to empty state if input value is empty\n    if (!inputValue.length) {\n      safelySetColorValue(null);\n      if (value === undefined || colorValue === null) {\n        setInputValue('');\n      } else {\n        setInputValue(colorValue.toString('hex'));\n      }\n      return;\n    }\n\n    // if it failed to parse, then reset input to formatted version of current number\n    if (parsedValue == null) {\n      setInputValue(colorValue ? colorValue.toString('hex') : '');\n      return;\n    }\n\n    safelySetColorValue(parsedValue);\n    // in a controlled state, the numberValue won't change, so we won't go back to our old input without help\n    let newColorValue = '';\n    if (colorValue) {\n      newColorValue = colorValue.toString('hex');\n    }\n    setInputValue(newColorValue);\n    validation.commitValidation();\n  };\n\n  let increment = () => {\n    let newValue = addColorValue(parsedValue, step);\n    // if we've arrived at the same value that was previously in the state, the\n    // input value should be updated to match\n    // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n    // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n    if (newValue === colorValue) {\n      setInputValue(newValue.toString('hex'));\n    }\n    safelySetColorValue(newValue);\n    validation.commitValidation();\n  };\n  let decrement = () => {\n    let newValue = addColorValue(parsedValue, -step);\n    // if we've arrived at the same value that was previously in the state, the\n    // input value should be updated to match\n    // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n    // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n    if (newValue === colorValue) {\n      setInputValue(newValue.toString('hex'));\n    }\n    safelySetColorValue(newValue);\n    validation.commitValidation();\n  };\n  let incrementToMax = () => safelySetColorValue(MAX_COLOR);\n  let decrementToMin = () => safelySetColorValue(MIN_COLOR);\n\n  let validate = (value: string) => value === '' || !!value.match(/^#?[0-9a-f]{0,6}$/i)?.[0];\n\n  return {\n    ...validation,\n    validate,\n    colorValue,\n    defaultColorValue: initialDefaultValue ?? initialValue,\n    setColorValue,\n    inputValue,\n    setInputValue,\n    commit,\n    increment,\n    incrementToMax,\n    decrement,\n    decrementToMin\n  };\n}\n\nfunction addColorValue(color: Color, step: number) {\n  let newColor = color ? color : MIN_COLOR;\n  let colorInt = newColor.toHexInt();\n\n  let clampInt = Math.min(Math.max(colorInt + step, MIN_COLOR_INT), MAX_COLOR_INT);\n  if (clampInt !== colorInt) {\n    let newColorString = `#${clampInt.toString(16).padStart(6, '0').toUpperCase()}`;\n    newColor = parseColor(newColorString);\n  }\n  return newColor;\n}\n"],"names":[],"version":3,"file":"useColorFieldState.mjs.map"}