UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

90 lines (89 loc) 4.4 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { useControlledState, useForkRef, useUniqId } from "../../../hooks/index.js"; import { useFormResetHandler } from "../../../hooks/private/index.js"; import { block } from "../../utils/cn.js"; import { ClearButton, mapTextInputSizeToButtonSize } from "../common/index.js"; import { OuterAdditionalContent } from "../common/OuterAdditionalContent/OuterAdditionalContent.js"; import { errorPropsMapper, getInputControlState, prepareAutoComplete } from "../utils.js"; import { TextAreaControl } from "./TextAreaControl.js"; import "./TextArea.css"; const b = block('text-area'); export const TextArea = React.forwardRef(function TextArea(props, ref) { const { view = 'normal', size = 'm', pin = 'round-round', name, value, defaultValue, disabled, readOnly, hasClear = false, error, errorMessage: errorMessageProp, validationState: validationStateProp, autoComplete, id: idProp, tabIndex, style, className, qa, controlProps, note, onUpdate, onChange, } = props; const { errorMessage, validationState } = errorPropsMapper({ error, errorMessage: errorMessageProp, validationState: validationStateProp, }); const [inputValue, setInputValue] = useControlledState(value, defaultValue ?? '', onUpdate); const innerControlRef = React.useRef(null); const fieldRef = useFormResetHandler({ initialValue: inputValue, onReset: setInputValue }); const handleRef = useForkRef(props.controlRef, innerControlRef, fieldRef); const [hasVerticalScrollbar, setHasVerticalScrollbar] = React.useState(false); const state = getInputControlState(validationState); const innerId = useUniqId(); const isErrorMsgVisible = validationState === 'invalid' && Boolean(errorMessage); const isClearControlVisible = Boolean(hasClear && !disabled && !readOnly && inputValue); const id = idProp || innerId; const errorMessageId = useUniqId(); const noteId = useUniqId(); const ariaDescribedBy = [ controlProps?.['aria-describedby'], note ? noteId : undefined, isErrorMsgVisible ? errorMessageId : undefined, ] .filter(Boolean) .join(' '); const commonProps = { id, tabIndex, name, onChange(event) { setInputValue(event.target.value); if (onChange) { onChange(event); } }, autoComplete: prepareAutoComplete(autoComplete), controlProps: { ...controlProps, 'aria-describedby': ariaDescribedBy || undefined, 'aria-invalid': validationState === 'invalid' || undefined, }, }; const handleClear = (event) => { const control = innerControlRef.current; if (control) { control.focus(); const syntheticEvent = Object.create(event); syntheticEvent.target = control; syntheticEvent.currentTarget = control; control.value = ''; if (onChange) { onChange(syntheticEvent); } } setInputValue(''); }; React.useEffect(() => { const control = innerControlRef.current; if (control) { const currHasVerticalScrollbar = control.scrollHeight > control.clientHeight; if (hasVerticalScrollbar !== currHasVerticalScrollbar) { setHasVerticalScrollbar(currHasVerticalScrollbar); } } }, [inputValue, hasVerticalScrollbar]); return (_jsxs("span", { ref: ref, style: style, className: b({ view, size, disabled, state, pin: view === 'clear' ? undefined : pin, 'has-clear': isClearControlVisible, 'has-scrollbar': hasVerticalScrollbar, }, className), "data-qa": qa, children: [_jsxs("span", { className: b('content'), children: [_jsx(TextAreaControl, { ...props, ...commonProps, controlRef: handleRef }), isClearControlVisible && (_jsx(ClearButton, { className: b('clear', { size }), size: mapTextInputSizeToButtonSize(size), onClick: handleClear }))] }), _jsx(OuterAdditionalContent, { errorMessage: isErrorMsgVisible ? errorMessage : null, errorMessageId: errorMessageId, note: note, noteId: noteId })] })); }); //# sourceMappingURL=TextArea.js.map