import { Accessibility, textAreaBehavior, TextAreaBehaviorProps } from '@fluentui/accessibility'; import { ComponentEventHandler, FluentComponentStaticProps } from '../../types'; import * as _ from 'lodash'; import * as React from 'react'; import * as PropTypes from 'prop-types'; import { UIComponentProps, ChildrenComponentProps, commonPropTypes, createShorthandFactory } from '../../utils'; import { ComponentWithAs, useAutoControlled, getElementType, useTelemetry, useUnhandledProps, useFluentContext, useAccessibility, useStyles, } from '@fluentui/react-bindings'; export interface TextAreaProps extends UIComponentProps, ChildrenComponentProps { /** Accessibility behavior if overridden by the user. */ accessibility?: Accessibility; /** The default value of the text area. */ defaultValue?: string; /** * Called on change. * * @param event - React's original SyntheticEvent. * @param data - All props. */ onChange?: ComponentEventHandler; /** The value of the text area. */ value?: string; /** The text area becomes read-only. */ disabled?: boolean; /** An input can have inverted colors. */ inverted?: boolean; /** A textarea can be resized. */ resize?: 'none' | 'both' | 'horizontal' | 'vertical'; /** A textarea can take the width of its container. */ fluid?: boolean; } export type TextAreaStylesProps = Required>; export const textAreaClassName = 'ui-textarea'; /** * A TextArea is a multi-line plan-text editing control. * * @accessibility * For good screen reader experience set `aria-label` or `aria-labelledby` attribute for textarea. * When using maxlength attribute, provide the information about max length in label for screen reader. * @accessibilityIssues * [NVDA - No announcement of maxlength](https://github.com/nvaccess/nvda/issues/7910) * [JAWS - textarea - no announcement of maxlength](https://github.com/FreedomScientific/VFO-standards-support/issues/300) */ export const TextArea: ComponentWithAs<'textarea', TextAreaProps> & FluentComponentStaticProps = props => { const context = useFluentContext(); const { setStart, setEnd } = useTelemetry(TextArea.displayName, context.telemetry); setStart(); const { disabled, accessibility, inverted, resize, fluid, className, design, styles, variables } = props; const [value, setValue] = useAutoControlled({ defaultValue: props.defaultValue, value: props.value, initialValue: '', }); const unhandledProps = useUnhandledProps(TextArea.handledProps, props); const getA11yProps = useAccessibility(accessibility, { debugName: TextArea.displayName, mapPropsToBehavior: () => ({ disabled, }), rtl: context.rtl, }); const { classes } = useStyles(TextArea.displayName, { className: textAreaClassName, mapPropsToStyles: () => ({ inverted, resize, fluid, disabled, }), mapPropsToInlineStyles: () => ({ className, design, styles, variables, }), rtl: context.rtl, }); const ElementType = getElementType(props); const handleChange = (e: React.ChangeEvent | React.FormEvent) => { const newValue = _.get(e, 'target.value'); _.invoke(props, 'onChange', e, { ...props, value: newValue }); setValue(newValue); }; const element = ( ); setEnd(); return element; }; TextArea.displayName = 'TextArea'; TextArea.propTypes = { ...commonPropTypes.createCommon({ content: false, }), defaultValue: PropTypes.string, onChange: PropTypes.func, value: PropTypes.string, disabled: PropTypes.bool, inverted: PropTypes.bool, }; TextArea.defaultProps = { as: 'textarea', accessibility: textAreaBehavior, }; TextArea.handledProps = Object.keys(TextArea.propTypes) as any; TextArea.create = createShorthandFactory({ Component: TextArea, });