diff --git a/packages/index.ts b/packages/index.ts index bc94ebe10..b1a1d3b42 100644 --- a/packages/index.ts +++ b/packages/index.ts @@ -50,6 +50,7 @@ export { NumberCell } from "./table"; export { TextInput, TextInputWithIcon } from "./textInput"; +export { Textarea } from "./textarea"; export { Toaster, Toast } from "./toaster"; export { ToggleContent } from "./toggleContent"; export { ToggleInput } from "./toggleInput"; diff --git a/packages/textarea/README.md b/packages/textarea/README.md new file mode 100644 index 000000000..2af6a21c6 --- /dev/null +++ b/packages/textarea/README.md @@ -0,0 +1,5 @@ +# Textarea + +A Textarea is used to input a large amount of text data in a form field. They're very similar to a regular text input, but they support multiple lines of text. + +By default, the Textarea height is big enough to hold 3 lines of text. Adjust this using the `rows` prop to give users a hint of how much content the field expects. diff --git a/packages/textarea/components/Textarea.tsx b/packages/textarea/components/Textarea.tsx new file mode 100644 index 000000000..cd7617d82 --- /dev/null +++ b/packages/textarea/components/Textarea.tsx @@ -0,0 +1,114 @@ +import * as React from "react"; +import { InputAppearance } from "../../shared/types/inputAppearance"; +import FormFieldWrapper from "../../shared/components/FormFieldWrapper"; +import { cx } from "emotion"; +import { + inputReset, + tintText, + visuallyHidden +} from "../../shared/styles/styleUtils"; +import { + getInputAppearanceStyle, + inputContainer, + getLabelStyle +} from "../../shared/styles/formStyles"; +import { textarea } from "../style"; +import { themeError } from "../../design-tokens/build/js/designTokens"; + +export interface TextareaProps extends React.HTMLProps { + /** + * Unique identifier used for the form textarea element + */ + id: string; + /** + * Sets the current appearance of the component. This defaults to InputAppearance.Standard, but supports `InputAppearance.Error` & `InputAppearance.Success` appearances as well. + */ + appearance: InputAppearance; + /** + * Sets the contents of the label. This can be a `string` or any `ReactNode`. + */ + inputLabel: React.ReactNode; + /** + * Defaults to `true`, but can be set to `false` to visibly hide the `Textarea`'s label. The `inputLabel` should still be set even when hidden for accessibility support. + */ + showInputLabel: boolean; + /** + * Text or a ReactNode that is displayed directly under the textarea with additional information about the expected input. + */ + hintContent?: React.ReactNode; + /** + * Sets the contents for validation errors. This will be displayed below the textarea element. Errors are only visible when the `Textarea` appearance is also set to `InputAppearance.Error`. + */ + errors?: React.ReactNode[]; +} + +class Textarea extends React.PureComponent { + public static defaultProps: Partial = { + appearance: InputAppearance.Standard, + showInputLabel: true, + rows: 3 + }; + + public render() { + const { + appearance, + errors, + hintContent, + id, + inputLabel, + required, + showInputLabel, + value, + ...other + } = this.props; + const hasError = appearance === InputAppearance.Error; + let { onChange } = other; + if (onChange == null && value != null) { + onChange = Function.prototype as ( + event: React.FormEvent + ) => void; + } + + return ( + + {({ getValidationErrors, getHintContent, isValid, describedByIds }) => ( +
+ +