UNPKG

@hitachivantara/uikit-react-core

Version:

Core React components for the NEXT Design System.

279 lines (278 loc) 9.66 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const jsxRuntime = require("react/jsx-runtime"); const React = require("react"); const utils = require("@mui/material/utils"); const uikitReactUtils = require("@hitachivantara/uikit-react-utils"); const validations = require("../BaseInput/validations.cjs"); const LabelContainer = require("../FormElement/LabelContainer.cjs"); const useControlled = require("../hooks/useControlled.cjs"); const useUniqueId = require("../hooks/useUniqueId.cjs"); const setId = require("../utils/setId.cjs"); const TextArea_styles = require("./TextArea.styles.cjs"); const FormElement = require("../FormElement/FormElement.cjs"); const CharCounter = require("../FormElement/CharCounter/CharCounter.cjs"); const BaseInput = require("../BaseInput/BaseInput.cjs"); const utils$1 = require("../FormElement/utils.cjs"); const WarningText = require("../FormElement/WarningText/WarningText.cjs"); const InfoMessage = require("../FormElement/InfoMessage/InfoMessage.cjs"); const HvTextArea = React.forwardRef(function HvTextArea2(props, ref) { const { id, className, classes: classesProp, name, label, description: descriptionProp, placeholder, status, statusMessage, infoMessage: infoMessageProp, validationMessages, maxCharQuantity, minCharQuantity, value: valueProp, inputRef: inputRefProp, rows = 1, defaultValue = "", middleCountLabel = "/", countCharProps, inputProps, required, readOnly, disabled, autoFocus, resizable, autoScroll, hideCounter, blockMax, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, validation, onChange, onBlur, onFocus, ...others } = uikitReactUtils.useDefaultProps("HvTextArea", props); const { classes, cx } = TextArea_styles.useClasses(classesProp); const elementId = useUniqueId.useUniqueId(id); const { activeTheme } = uikitReactUtils.useTheme(); const isDirty = React.useRef(false); const inputRef = React.useRef(null); const forkedRef = utils.useForkRef(ref, inputRefProp, inputRef); const [description, infoMessage] = activeTheme?.name === "pentahoPlus" ? [infoMessageProp, descriptionProp] : [descriptionProp, infoMessageProp]; const [focused, setFocused] = React.useState(false); const [autoScrolling, setAutoScrolling] = React.useState(autoScroll); const [validationState, setValidationState] = useControlled.useControlled( status, "standBy" ); const [validationMessage, setValidationMessage] = useControlled.useControlled( statusMessage, "" ); const [value, setValue] = useControlled.useControlled(valueProp, defaultValue); const isStateInvalid = utils$1.isInvalid(validationState); const isEmptyValue = value == null || value === ""; const hasLabel = label != null; const hasCounter = maxCharQuantity != null && !hideCounter; const errorMessages = React.useMemo( () => ({ ...validations.DEFAULT_ERROR_MESSAGES, ...validationMessages }), [validationMessages] ); const performValidation = React.useCallback(() => { const inputValidity = validations.validateInput( inputRef.current, required, minCharQuantity, maxCharQuantity, "none", validation ); setValidationState(validations.computeValidationState(inputValidity, isEmptyValue)); setValidationMessage( validations.computeValidationMessage(inputValidity, errorMessages) ); return inputValidity; }, [ errorMessages, inputRef, isEmptyValue, maxCharQuantity, minCharQuantity, required, setValidationMessage, setValidationState, validation ]); const limitValue = (currentValue) => { if (currentValue === void 0 || !blockMax) return currentValue; const isOverflow = maxCharQuantity == null ? false : currentValue.length > maxCharQuantity; return !isOverflow ? currentValue : currentValue.substring(0, maxCharQuantity); }; const onContainerBlurHandler = (event) => { setFocused(false); const inputValidity = performValidation(); onBlur?.(event, String(value), inputValidity); }; const onChangeHandler = (event, currentValue) => { isDirty.current = true; const limitedValue = blockMax ? limitValue(currentValue) : currentValue; setValue(limitedValue); onChange?.(event, limitedValue); }; const onFocusHandler = (event) => { setFocused(true); setValidationState("standBy"); onFocus?.(event, String(value)); }; const isScrolledDown = React.useCallback(() => { const el = inputRef.current; return el == null || el.offsetHeight + el.scrollTop >= el.scrollHeight; }, [inputRef]); const scrollDown = React.useCallback(() => { const el = inputRef.current; if (el != null) { el.scrollTop = el.scrollHeight - el.clientHeight; } }, [inputRef]); const addScrollListener = React.useCallback(() => { const scrollHandler = { handleEvent: () => { setAutoScrolling(isScrolledDown()); } }; inputRef.current?.addEventListener("scroll", scrollHandler); }, [inputRef, isScrolledDown]); React.useEffect(() => { if (autoScroll) { addScrollListener(); } }, [autoScroll, addScrollListener]); React.useEffect(() => { if (autoScrolling) { scrollDown(); } }, [valueProp, autoScrolling, scrollDown]); React.useEffect(() => { if (focused || !isDirty.current && isEmptyValue) { return; } performValidation(); }, [focused, isEmptyValue, performValidation]); const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && validations.hasBuiltInValidations( required, "none", minCharQuantity, // If blockMax is true maxCharQuantity will never produce an error // unless the value is controlled, so we can't prevent it to overflow maxCharQuantity maxCharQuantity != null && (blockMax !== true || value != null) ? maxCharQuantity : null, validation, inputProps )); const willShowError = canShowError && isStateInvalid; const canShowInfo = !!infoMessage && !willShowError; let errorMessageId; if (isStateInvalid) { errorMessageId = canShowError ? setId.setId(elementId, "error") : ariaErrorMessage; } return /* @__PURE__ */ jsxRuntime.jsxs( FormElement.HvFormElement, { id, name, status: validationState, disabled, required, readOnly, className: cx( classes.root, { [classes.resizable]: resizable, [classes.disabled]: disabled, [classes.invalid]: isStateInvalid }, className ), onBlur: onContainerBlurHandler, children: [ /* @__PURE__ */ jsxRuntime.jsx( LabelContainer.HvLabelContainer, { label, description, inputId: setId.setId(elementId, "input"), labelId: setId.setId(elementId, "label"), descriptionId: setId.setId(elementId, "description"), classes: { root: classes.labelContainer, label: classes.label, description: classes.description }, children: hasCounter && /* @__PURE__ */ jsxRuntime.jsx( CharCounter.HvCharCounter, { disableGutter: true, id: setId.setId(elementId, "charCounter"), className: classes.characterCounter, separator: middleCountLabel, currentCharQuantity: String(value).length, maxCharQuantity, ...countCharProps } ) } ), /* @__PURE__ */ jsxRuntime.jsx( BaseInput.HvBaseInput, { classes: { root: classes.baseInput, input: classes.input, inputResizable: classes.inputResizable }, id: hasLabel ? setId.setId(elementId, "input") : setId.setId(id, "input"), name, value, required, readOnly, disabled, onChange: onChangeHandler, autoFocus, onFocus: onFocusHandler, placeholder, invalid: isStateInvalid, resizable, multiline: true, rows, inputProps: { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-invalid": isStateInvalid ? true : void 0, "aria-errormessage": errorMessageId, "aria-describedby": ariaDescribedBy != null ? ariaDescribedBy : description && setId.setId(elementId, "description") || void 0, "aria-controls": maxCharQuantity ? setId.setId(elementId, "charCounter") : void 0, ...inputProps }, inputRef: forkedRef, ...others } ), canShowError && /* @__PURE__ */ jsxRuntime.jsx( WarningText.HvWarningText, { id: setId.setId(elementId, "error"), className: classes.error, disableBorder: true, children: validationMessage } ), canShowInfo && /* @__PURE__ */ jsxRuntime.jsx(InfoMessage.HvInfoMessage, { disableGutter: true, variant: "caption1", children: infoMessage }) ] } ); }); exports.textAreaClasses = TextArea_styles.staticClasses; exports.HvTextArea = HvTextArea;