VariableTextAreaField.tsx 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { css } from '@emotion/css';
  2. import React, { FormEvent, PropsWithChildren, ReactElement, useCallback } from 'react';
  3. import { GrafanaTheme } from '@grafana/data';
  4. import { InlineField, TextArea, useStyles } from '@grafana/ui';
  5. interface VariableTextAreaFieldProps<T> {
  6. name: string;
  7. value: string;
  8. placeholder: string;
  9. onChange: (event: FormEvent<HTMLTextAreaElement>) => void;
  10. width: number;
  11. tooltip?: string;
  12. ariaLabel?: string;
  13. required?: boolean;
  14. labelWidth?: number;
  15. testId?: string;
  16. onBlur?: (event: FormEvent<HTMLTextAreaElement>) => void;
  17. }
  18. export function VariableTextAreaField({
  19. name,
  20. value,
  21. placeholder,
  22. tooltip,
  23. onChange,
  24. onBlur,
  25. ariaLabel,
  26. required,
  27. width,
  28. labelWidth,
  29. testId,
  30. }: PropsWithChildren<VariableTextAreaFieldProps<any>>): ReactElement {
  31. const styles = useStyles(getStyles);
  32. const getLineCount = useCallback((value: any) => {
  33. if (value && typeof value === 'string') {
  34. return value.split('\n').length;
  35. }
  36. return 1;
  37. }, []);
  38. return (
  39. <InlineField label={name} labelWidth={labelWidth ?? 12} tooltip={tooltip}>
  40. <TextArea
  41. rows={getLineCount(value)}
  42. value={value}
  43. onChange={onChange}
  44. onBlur={onBlur}
  45. placeholder={placeholder}
  46. required={required}
  47. aria-label={ariaLabel}
  48. cols={width}
  49. className={styles.textarea}
  50. data-testid={testId}
  51. />
  52. </InlineField>
  53. );
  54. }
  55. function getStyles(theme: GrafanaTheme) {
  56. return {
  57. textarea: css`
  58. white-space: pre-wrap;
  59. min-height: 32px;
  60. height: auto;
  61. overflow: auto;
  62. padding: 6px 8px;
  63. `,
  64. };
  65. }