{"version":3,"file":"AutoSizeInput.mjs","sources":["../../../../src/components/Input/AutoSizeInput.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from 'react';\nimport * as React from 'react';\n\nimport { measureText } from '../../utils/measureText';\n\nimport { AutoSizeInputContext } from './AutoSizeInputContext';\nimport { Input, Props as InputProps } from './Input';\n\nexport interface Props extends InputProps {\n  /** Sets the min-width to a multiple of 8px. Default value is 10*/\n  minWidth?: number;\n  /** Sets the max-width to a multiple of 8px.*/\n  maxWidth?: number;\n  /** onChange function that will be run on onBlur and onKeyPress with enter\n   * @deprecated Use `onChange` instead and manage the value in the parent as a controlled input\n   */\n  onCommitChange?: (event: React.FormEvent<HTMLInputElement>) => void;\n\n  /** @deprecated Use `value` and `onChange` instead to manage the value in the parent as a controlled input */\n  defaultValue?: string | number | readonly string[];\n}\n\n/**\n * You can use it or regular text input. When used, AutoSizeInput resizes itself to the current content. For an array of data or tree-structured data, consider using `Combobox` or `Cascader` respectively.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/inputs-autosizeinput--docs\n */\nexport const AutoSizeInput = React.forwardRef<HTMLInputElement, Props>((props, ref) => {\n  const {\n    defaultValue = '',\n    minWidth = 10,\n    maxWidth,\n    onCommitChange,\n    onChange,\n    onKeyDown,\n    onBlur,\n    value: controlledValue,\n    placeholder,\n    ...restProps\n  } = props;\n  const [inputState, setInputValue] = useControlledState(controlledValue, onChange);\n\n  // This must use ?? instead of || so the default value is not used when the value is an empty string\n  // typically from the user clearing the input\n  const inputValue = inputState ?? defaultValue;\n\n  // Update input width when `value`, `minWidth`, or `maxWidth` change\n  const inputWidth = useMemo(() => {\n    const displayValue = inputValue || placeholder || '';\n    const valueString = typeof displayValue === 'string' ? displayValue : displayValue.toString();\n\n    return getWidthFor(valueString, minWidth, maxWidth);\n  }, [placeholder, inputValue, minWidth, maxWidth]);\n\n  return (\n    <AutoSizeInputContext.Provider value={true}>\n      <Input\n        data-testid=\"autosize-input\" // consumer should override default testid\n        {...restProps}\n        placeholder={placeholder}\n        ref={ref}\n        value={inputValue.toString()}\n        onChange={(event) => {\n          if (onChange) {\n            onChange(event);\n          }\n\n          setInputValue(event.currentTarget.value);\n        }}\n        width={inputWidth}\n        onBlur={(event) => {\n          if (onBlur) {\n            onBlur(event);\n          } else if (onCommitChange) {\n            onCommitChange(event);\n          }\n        }}\n        onKeyDown={(event) => {\n          if (onKeyDown) {\n            onKeyDown(event);\n          } else if (event.key === 'Enter' && onCommitChange) {\n            onCommitChange(event);\n          }\n        }}\n      />\n    </AutoSizeInputContext.Provider>\n  );\n});\n\nfunction getWidthFor(value: string, minWidth: number, maxWidth: number | undefined): number {\n  if (!value) {\n    return minWidth;\n  }\n\n  const extraSpace = 3;\n  const realWidth = measureText(value.toString(), 14).width / 8 + extraSpace;\n\n  if (minWidth && realWidth < minWidth) {\n    return minWidth;\n  }\n\n  if (maxWidth && realWidth > maxWidth) {\n    return maxWidth;\n  }\n\n  return realWidth;\n}\n\nAutoSizeInput.displayName = 'AutoSizeInput';\n\n/**\n * Hook to abstract away state management for controlled and uncontrolled inputs.\n * If the initial value is not undefined, then the value will be controlled by the parent\n * for the lifetime of the component and calls to setState will be ignored.\n */\nfunction useControlledState<T>(controlledValue: T, onChange: Function | undefined): [T, (newValue: T) => void] {\n  const isControlledNow = controlledValue !== undefined && onChange !== undefined;\n  const isControlledRef = useRef(isControlledNow); // set the initial value - we never change this\n\n  const hasLoggedControlledWarning = useRef(false);\n  if (isControlledNow !== isControlledRef.current && !hasLoggedControlledWarning.current) {\n    console.warn(\n      'An AutoSizeInput is changing from an uncontrolled to a controlled input. If you want to control the input, the empty value should be an empty string.'\n    );\n    hasLoggedControlledWarning.current = true;\n  }\n\n  const [internalValue, setInternalValue] = React.useState(controlledValue);\n\n  useEffect(() => {\n    if (!isControlledRef.current) {\n      setInternalValue(controlledValue);\n    }\n  }, [controlledValue]);\n\n  const handleChange = useCallback((newValue: T) => {\n    if (!isControlledRef.current) {\n      setInternalValue(newValue);\n    }\n  }, []);\n\n  const value = isControlledRef.current ? controlledValue : internalValue;\n\n  return [value, handleChange];\n}\n"],"names":[],"mappings":"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"}