Design system.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

136 wiersze
3.2 KiB

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