Design system.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

128 rivejä
3.1 KiB

  1. import * as React from 'react';
  2. import * as TextControlBase from '@tesseract-design/web-base-textcontrol';
  3. export type MultilineTextInputProps = Omit<React.HTMLProps<HTMLTextAreaElement>, 'size' | 'style'> & {
  4. /**
  5. * Short textual description indicating the nature of the component's value.
  6. */
  7. label?: React.ReactNode,
  8. /**
  9. * Short textual description as guidelines for valid input values.
  10. */
  11. hint?: React.ReactNode,
  12. /**
  13. * Size of the component.
  14. */
  15. size?: TextControlBase.TextControlSize,
  16. /**
  17. * Additional description, usually graphical, indicating the nature of the component's value.
  18. */
  19. indicator?: React.ReactNode,
  20. /**
  21. * Should the component display a border?
  22. */
  23. border?: boolean,
  24. /**
  25. * Should the component occupy the whole width of its parent?
  26. */
  27. block?: boolean,
  28. /**
  29. * Style of the component.
  30. */
  31. style?: TextControlBase.TextControlStyle,
  32. /**
  33. * Is the label hidden?
  34. */
  35. hiddenLabel?: boolean,
  36. }
  37. /**
  38. * Component for inputting textual values.
  39. *
  40. * This component supports multiline input and adjusts its layout accordingly.
  41. */
  42. export const MultilineTextInput = React.forwardRef<HTMLTextAreaElement, MultilineTextInputProps>(
  43. (
  44. {
  45. label = '',
  46. hint = '',
  47. indicator = null,
  48. size = TextControlBase.TextControlSize.MEDIUM,
  49. border = false,
  50. block = false,
  51. style = TextControlBase.TextControlStyle.DEFAULT,
  52. hiddenLabel = false,
  53. className: _className,
  54. placeholder: _placeholder,
  55. as: _as,
  56. ...etcProps
  57. }: MultilineTextInputProps,
  58. ref,
  59. ) => {
  60. const textInputBaseArgs = React.useMemo<TextControlBase.TextControlBaseArgs>(() => ({
  61. block,
  62. border,
  63. size,
  64. indicator: Boolean(indicator),
  65. style,
  66. resizable: true,
  67. predefinedValues: false,
  68. }), [block, border, size, indicator, style]);
  69. return (
  70. <div
  71. className={TextControlBase.Root(textInputBaseArgs)}
  72. >
  73. <textarea
  74. {...etcProps}
  75. className={TextControlBase.Input(textInputBaseArgs)}
  76. ref={ref}
  77. aria-label={label}
  78. style={{
  79. height: TextControlBase.MIN_HEIGHTS[size],
  80. }}
  81. data-testid="input"
  82. />
  83. {
  84. border && (
  85. <span
  86. data-testid="border"
  87. />
  88. )
  89. }
  90. {
  91. label && !hiddenLabel && (
  92. <div
  93. data-testid="label"
  94. className={TextControlBase.LabelWrapper(textInputBaseArgs)}
  95. >
  96. {label}
  97. </div>
  98. )
  99. }
  100. {hint && (
  101. <div
  102. className={TextControlBase.HintWrapper(textInputBaseArgs)}
  103. data-testid="hint"
  104. >
  105. <div
  106. className={TextControlBase.Hint()}
  107. >
  108. {hint}
  109. </div>
  110. </div>
  111. )}
  112. {indicator && (
  113. <div
  114. className={TextControlBase.IndicatorWrapper(textInputBaseArgs)}
  115. >
  116. {indicator}
  117. </div>
  118. )}
  119. </div>
  120. );
  121. }
  122. );
  123. MultilineTextInput.displayName = 'MultilineTextInput';