@grafana/ui
Version:
Grafana Components Library
1 lines • 7.6 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\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":";;;;;;;AAsBO,MAAM,aAAgB,GAAA,KAAA,CAAM,UAAoC,CAAA,CAAC,OAAO,GAAQ,KAAA;AACrF,EAAM,MAAA;AAAA,IACJ,YAAe,GAAA,EAAA;AAAA,IACf,QAAW,GAAA,EAAA;AAAA,IACX,QAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAO,EAAA,eAAA;AAAA,IACP,WAAA;AAAA,IACA,GAAG;AAAA,GACD,GAAA,KAAA;AACJ,EAAA,MAAM,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,kBAAA,CAAmB,iBAAiB,QAAQ,CAAA;AAIhF,EAAA,MAAM,aAAa,UAAc,IAAA,IAAA,GAAA,UAAA,GAAA,YAAA;AAGjC,EAAM,MAAA,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAM,MAAA,YAAA,GAAe,cAAc,WAAe,IAAA,EAAA;AAClD,IAAA,MAAM,cAAc,OAAO,YAAA,KAAiB,QAAW,GAAA,YAAA,GAAe,aAAa,QAAS,EAAA;AAE5F,IAAO,OAAA,WAAA,CAAY,WAAa,EAAA,QAAA,EAAU,QAAQ,CAAA;AAAA,KACjD,CAAC,WAAA,EAAa,UAAY,EAAA,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEhD,EAAA,uBACG,GAAA,CAAA,oBAAA,CAAqB,QAArB,EAAA,EAA8B,OAAO,IACpC,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,gBAAA;AAAA,MACX,GAAG,SAAA;AAAA,MACJ,WAAA;AAAA,MACA,GAAA;AAAA,MACA,KAAA,EAAO,WAAW,QAAS,EAAA;AAAA,MAC3B,QAAA,EAAU,CAAC,KAAU,KAAA;AACnB,QAAA,IAAI,QAAU,EAAA;AACZ,UAAA,QAAA,CAAS,KAAK,CAAA;AAAA;AAGhB,QAAc,aAAA,CAAA,KAAA,CAAM,cAAc,KAAK,CAAA;AAAA,OACzC;AAAA,MACA,KAAO,EAAA,UAAA;AAAA,MACP,MAAA,EAAQ,CAAC,KAAU,KAAA;AACjB,QAAA,IAAI,MAAQ,EAAA;AACV,UAAA,MAAA,CAAO,KAAK,CAAA;AAAA,mBACH,cAAgB,EAAA;AACzB,UAAA,cAAA,CAAe,KAAK,CAAA;AAAA;AACtB,OACF;AAAA,MACA,SAAA,EAAW,CAAC,KAAU,KAAA;AACpB,QAAA,IAAI,SAAW,EAAA;AACb,UAAA,SAAA,CAAU,KAAK,CAAA;AAAA,SACN,MAAA,IAAA,KAAA,CAAM,GAAQ,KAAA,OAAA,IAAW,cAAgB,EAAA;AAClD,UAAA,cAAA,CAAe,KAAK,CAAA;AAAA;AACtB;AACF;AAAA,GAEJ,EAAA,CAAA;AAEJ,CAAC;AAED,SAAS,WAAA,CAAY,KAAe,EAAA,QAAA,EAAkB,QAAsC,EAAA;AAC1F,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAO,OAAA,QAAA;AAAA;AAGT,EAAA,MAAM,UAAa,GAAA,CAAA;AACnB,EAAM,MAAA,SAAA,GAAY,YAAY,KAAM,CAAA,QAAA,IAAY,EAAE,CAAA,CAAE,QAAQ,CAAI,GAAA,UAAA;AAEhE,EAAI,IAAA,QAAA,IAAY,YAAY,QAAU,EAAA;AACpC,IAAO,OAAA,QAAA;AAAA;AAGT,EAAI,IAAA,QAAA,IAAY,YAAY,QAAU,EAAA;AACpC,IAAO,OAAA,QAAA;AAAA;AAGT,EAAO,OAAA,SAAA;AACT;AAEA,aAAA,CAAc,WAAc,GAAA,eAAA;AAO5B,SAAS,kBAAA,CAAsB,iBAAoB,QAA4D,EAAA;AAC7G,EAAM,MAAA,eAAA,GAAkB,eAAoB,KAAA,KAAA,CAAA,IAAa,QAAa,KAAA,KAAA,CAAA;AACtE,EAAM,MAAA,eAAA,GAAkB,OAAO,eAAe,CAAA;AAE9C,EAAM,MAAA,0BAAA,GAA6B,OAAO,KAAK,CAAA;AAC/C,EAAA,IAAI,eAAoB,KAAA,eAAA,CAAgB,OAAW,IAAA,CAAC,2BAA2B,OAAS,EAAA;AACtF,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,0BAAA,CAA2B,OAAU,GAAA,IAAA;AAAA;AAGvC,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,KAAA,CAAM,SAAS,eAAe,CAAA;AAExE,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,CAAC,gBAAgB,OAAS,EAAA;AAC5B,MAAA,gBAAA,CAAiB,eAAe,CAAA;AAAA;AAClC,GACF,EAAG,CAAC,eAAe,CAAC,CAAA;AAEpB,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,CAAC,QAAgB,KAAA;AAChD,IAAI,IAAA,CAAC,gBAAgB,OAAS,EAAA;AAC5B,MAAA,gBAAA,CAAiB,QAAQ,CAAA;AAAA;AAC3B,GACF,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,KAAA,GAAQ,eAAgB,CAAA,OAAA,GAAU,eAAkB,GAAA,aAAA;AAE1D,EAAO,OAAA,CAAC,OAAO,YAAY,CAAA;AAC7B;;;;"}