{"version":3,"file":"Input.mjs","sources":["../../../../src/components/Input/Input.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { forwardRef, HTMLProps, ReactNode, useContext } from 'react';\nimport useMeasure from 'react-use/lib/useMeasure';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { stylesFactory, useTheme2 } from '../../themes';\nimport { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles';\nimport { Spinner } from '../Spinner/Spinner';\n\nimport { AutoSizeInputContext } from './AutoSizeInputContext';\n\nexport interface Props extends Omit<HTMLProps<HTMLInputElement>, 'prefix' | 'size'> {\n  /** Sets the width to a multiple of 8px. Should only be used with inline forms. Setting width of the container is preferred in other cases.*/\n  width?: number;\n  /** Show an invalid state around the input */\n  invalid?: boolean;\n  /** Show an icon as a prefix in the input */\n  prefix?: ReactNode;\n  /** Show an icon as a suffix in the input */\n  suffix?: ReactNode;\n  /** Show a loading indicator as a suffix in the input */\n  loading?: boolean;\n  /** Add a component as an addon before the input  */\n  addonBefore?: ReactNode;\n  /** Add a component as an addon after the input */\n  addonAfter?: ReactNode;\n}\n\ninterface StyleDeps {\n  theme: GrafanaTheme2;\n  invalid?: boolean;\n  width?: number;\n}\n\nexport const Input = forwardRef<HTMLInputElement, Props>((props, ref) => {\n  const {\n    className,\n    addonAfter,\n    addonBefore,\n    prefix,\n    suffix: suffixProp,\n    invalid,\n    loading,\n    width = 0,\n    ...restProps\n  } = props;\n  /**\n   * Prefix & suffix are positioned absolutely within inputWrapper. We use client rects below to apply correct padding to the input\n   * when prefix/suffix is larger than default (28px = 16px(icon) + 12px(left/right paddings)).\n   * Thanks to that prefix/suffix do not overflow the input element itself.\n   */\n  const [prefixRef, prefixRect] = useMeasure<HTMLDivElement>();\n  const [suffixRef, suffixRect] = useMeasure<HTMLDivElement>();\n\n  // Yes, this is gross - When Input is being wrapped by AutoSizeInput, add the suffix/prefix width to the overall width\n  // so the text content is not clipped. The intention is to make all the input's text appear without overflow/clipping,\n  // which isn't normally how width is used in this component.\n  // This behaviour is not controlled via a prop so we can limit API surface, and remove this as a 'breaking change' later\n  // if a better solution is found.\n  const isInAutoSizeInput = useContext(AutoSizeInputContext);\n  const accessoriesWidth = (prefixRect.width || 0) + (suffixRect.width || 0);\n  const autoSizeWidth = isInAutoSizeInput && width ? width + accessoriesWidth / 8 : undefined;\n\n  const theme = useTheme2();\n\n  // Don't pass the width prop, as this causes an unnecessary amount of Emotion calls when auto sizing\n  const styles = getInputStyles({ theme, invalid: !!invalid, width: autoSizeWidth ? undefined : width });\n\n  const suffix = suffixProp || (loading && <Spinner inline={true} />);\n\n  return (\n    <div\n      className={cx(styles.wrapper, className)}\n      // If the component is in an AutoSizeInput, set the width here to prevent emotion doing stuff\n      // on every keypress\n      style={autoSizeWidth ? { width: theme.spacing(autoSizeWidth) } : undefined}\n      data-testid=\"input-wrapper\"\n    >\n      {!!addonBefore && <div className={styles.addon}>{addonBefore}</div>}\n      <div className={styles.inputWrapper}>\n        {prefix && (\n          <div className={styles.prefix} ref={prefixRef}>\n            {prefix}\n          </div>\n        )}\n\n        <input\n          ref={ref}\n          className={styles.input}\n          {...restProps}\n          style={{\n            paddingLeft: prefix ? prefixRect.width + 12 : undefined,\n            paddingRight: suffix || loading ? suffixRect.width + 12 : undefined,\n          }}\n        />\n\n        {suffix && (\n          <div className={styles.suffix} ref={suffixRef}>\n            {suffix}\n          </div>\n        )}\n      </div>\n      {!!addonAfter && <div className={styles.addon}>{addonAfter}</div>}\n    </div>\n  );\n});\n\nInput.displayName = 'Input';\n\nexport const getInputStyles = stylesFactory(({ theme, invalid = false, width }: StyleDeps) => {\n  const prefixSuffixStaticWidth = '28px';\n  const prefixSuffix = css({\n    position: 'absolute',\n    top: 0,\n    zIndex: 1,\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    flexGrow: 0,\n    flexShrink: 0,\n    fontSize: theme.typography.size.md,\n    height: '100%',\n    /* Min width specified for prefix/suffix classes used outside React component*/\n    minWidth: prefixSuffixStaticWidth,\n    color: theme.colors.text.secondary,\n  });\n\n  return {\n    // Wraps inputWrapper and addons\n    wrapper: cx(\n      css({\n        label: 'input-wrapper',\n        display: 'flex',\n        width: width ? theme.spacing(width) : '100%',\n        height: theme.spacing(theme.components.height.md),\n        borderRadius: theme.shape.radius.default,\n        '&:hover': {\n          '> .prefix, .suffix, .input': {\n            borderColor: invalid ? theme.colors.error.border : theme.colors.primary.border,\n          },\n\n          // only show number buttons on hover\n          \"input[type='number']\": {\n            appearance: 'textfield',\n          },\n\n          \"input[type='number']::-webkit-inner-spin-button, input[type='number']::-webkit-outer-spin-button\": {\n            // Need type assertion here due to the use of !important\n            // see https://github.com/frenic/csstype/issues/114#issuecomment-697201978\n            // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n            WebkitAppearance: 'inner-spin-button !important' as 'inner-spin-button',\n            opacity: 1,\n          },\n        },\n      })\n    ),\n    // Wraps input and prefix/suffix\n    inputWrapper: css({\n      label: 'input-inputWrapper',\n      position: 'relative',\n      flexGrow: 1,\n      /* we want input to be above addons, especially for focused state */\n      zIndex: 1,\n\n      /* when input rendered with addon before only*/\n      '&:not(:first-child):last-child': {\n        '> input': {\n          borderLeft: 'none',\n          borderTopLeftRadius: 0,\n          borderBottomLeftRadius: 0,\n        },\n      },\n\n      /* when input rendered with addon after only*/\n      '&:first-child:not(:last-child)': {\n        '> input': {\n          borderRight: 'none',\n          borderTopRightRadius: 0,\n          borderBottomRightRadius: 0,\n        },\n      },\n\n      /* when rendered with addon before and after */\n      '&:not(:first-child):not(:last-child)': {\n        '> input': {\n          borderRight: 'none',\n          borderTopRightRadius: 0,\n          borderBottomRightRadius: 0,\n          borderTopLeftRadius: 0,\n          borderBottomLeftRadius: 0,\n        },\n      },\n\n      input: {\n        /* paddings specified for classes used outside React component */\n        '&:not(:first-child)': {\n          paddingLeft: prefixSuffixStaticWidth,\n        },\n        '&:not(:last-child)': {\n          paddingRight: prefixSuffixStaticWidth,\n        },\n        '&[readonly]': {\n          cursor: 'default',\n        },\n      },\n    }),\n\n    input: cx(\n      getFocusStyle(theme),\n      sharedInputStyle(theme, invalid),\n      css({\n        label: 'input-input',\n        position: 'relative',\n        zIndex: 0,\n        flexGrow: 1,\n        borderRadius: theme.shape.radius.default,\n        height: '100%',\n        width: '100%',\n      })\n    ),\n    inputDisabled: css({\n      backgroundColor: theme.colors.action.disabledBackground,\n      color: theme.colors.action.disabledText,\n      border: `1px solid ${theme.colors.action.disabledBackground}`,\n      '&:focus': {\n        boxShadow: 'none',\n      },\n    }),\n    addon: css({\n      label: 'input-addon',\n      display: 'flex',\n      justifyContent: 'center',\n      alignItems: 'center',\n      flexGrow: 0,\n      flexShrink: 0,\n      position: 'relative',\n\n      '&:first-child': {\n        borderTopRightRadius: 0,\n        borderBottomRightRadius: 0,\n        '> :last-child': {\n          borderTopRightRadius: 0,\n          borderBottomRightRadius: 0,\n        },\n      },\n\n      '&:last-child': {\n        borderTopLeftRadius: 0,\n        borderBottomLeftRadius: 0,\n        '> :first-child': {\n          borderTopLeftRadius: 0,\n          borderBottomLeftRadius: 0,\n        },\n      },\n      '> *:focus': {\n        /* we want anything that has focus and is an addon to be above input */\n        zIndex: 2,\n      },\n    }),\n    prefix: cx(\n      prefixSuffix,\n      css({\n        label: 'input-prefix',\n        paddingLeft: theme.spacing(1),\n        paddingRight: theme.spacing(0.5),\n        borderRight: 'none',\n        borderTopRightRadius: 0,\n        borderBottomRightRadius: 0,\n      })\n    ),\n    suffix: cx(\n      prefixSuffix,\n      css({\n        label: 'input-suffix',\n        paddingLeft: theme.spacing(1),\n        paddingRight: theme.spacing(1),\n        marginBottom: '-2px',\n        borderLeft: 'none',\n        borderTopLeftRadius: 0,\n        borderBottomLeftRadius: 0,\n        right: 0,\n      })\n    ),\n    loadingIndicator: css({\n      '& + *': {\n        marginLeft: theme.spacing(0.5),\n      },\n    }),\n  };\n});\n"],"names":[],"mappings":"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"}