@grafana/ui
Version:
Grafana Components Library
1 lines • 8 kB
Source Map (JSON)
{"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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"}