Untitled

mail@pastecode.io avatar
unknown
plain_text
25 days ago
7.8 kB
2
Indexable
Never
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { InputTextarea } from 'primereact/inputtextarea';
import PrimeWrapper from '../primeWrapper/primeWrapper';
import PropTypes from 'prop-types';
import classNames from 'classnames';

const PrimeInputTextarea = (props) => {
    const {
        register,
        formState: { errors },
    } = useForm({
        mode: 'all',
    });
    const { model, validations, children, onBlur, onChange, ...rest } = props;

    const [inputValue, setInputValue] = useState(props.value || '');
    const [charsRemaining, setCharsRemaining] = useState(
        props.maxLength ? props.maxLength - (props.value?.length || 0) : 0
    );
    const [charsEntered, setCharsEntered] = useState(props.value?.length || 0);

    const calculateLength = props.calculateLength || ((str) => str.length);

    useEffect(() => {
        const initialText = props.value || '';
        setInputValue(initialText);
        setCharsEntered(calculateLength(initialText));
        setCharsRemaining(props.maxLength ? props.maxLength - calculateLength(initialText) : 0);
    }, [props.value, props.maxLength, calculateLength]);

    const handleInputChange = (event) => {
        let value = event.target.value;

        // Apply autoCapitalize if needed
        if (props.autoCapitalize) {
            value = value.toUpperCase();
        }

        const textLength = calculateLength(value);
        const remainingChars = props.maxLength ? props.maxLength - textLength : 0;

        if (remainingChars >= 0 || !props.maxLength || !props.truncate) {
            setInputValue(value);
            setCharsEntered(textLength);
            setCharsRemaining(remainingChars);
            props.onChange && props.onChange({ ...event, target: { ...event.target, value } });
        } else if (props.truncate) {
            const truncatedValue = value.slice(0, props.maxLength);
            setInputValue(truncatedValue);
            setCharsEntered(calculateLength(truncatedValue));
            setCharsRemaining(0);
            props.onChange && props.onChange({ ...event, target: { ...event.target, value: truncatedValue } });
        }
    };

    const getCharRemainingText = () => {
        const charRemainingText = props.charRemainingKey || 'You have {0} characters remaining.';
        return charRemainingText.replace(/\{0\}/g, charsRemaining);
    };

    const getCharEnteredText = () => {
        const charEnteredText = props.charEnteredKey || '{0} characters entered.';
        return charEnteredText.replace(/\{0\}/g, charsEntered);
    };

    return (
        (props.showif !== undefined ? props.showif : true) && (
            <span>
                <div>
                    <label className={props.labelClassName}>
                        {props.evalLangText(props.labelKey, props.label)}
                    </label>
                </div>
                <span>
                    <InputTextarea
                        {...rest}
                        value={inputValue}
                        onChange={handleInputChange}
                        onBlur={onBlur}
                        {...register(model, {
                            validate: validations,
                            onChange: handleInputChange,
                            onBlur,
                        })}
                    >
                        {children}
                    </InputTextarea>

                    {props.helperTextShowIf &&
                        (props.helperTextLabelKey || props.helperTextLabel) && (
                            <div>
                                <small
                                    className={classNames(
                                        'ux-input-helper-text',
                                        props.helperTextClassName
                                    )}
                                >
                                    {props.evalLangText(
                                        props.helperTextLabelKey,
                                        props.helperTextLabel
                                    )}
                                </small>
                            </div>
                        )}

                    {props.showRemaining && (
                        <div>
                            <small
                                id={`${props.id}_characterRemaining`}
                                className={classNames(
                                    `noChar_${charsRemaining === 0}`,
                                    props.charRemainingClass
                                )}
                            >
                                {getCharRemainingText()}
                            </small>
                        </div>
                    )}

                    {props.showCurrent && (
                        <div>
                            <small
                                id={`${props.id}_charEntered`}
                                className={classNames(
                                    `noChar_${charsEntered === parseInt(props.maxLength, 10)}`,
                                    props.charEnteredClass
                                )}
                            >
                                {getCharEnteredText()}
                            </small>
                        </div>
                    )}

                    {errors[model]?.message && (
                        <div
                            id={`errorMessageSpanForElementWithId_${props.id}`}
                            className="p-error"
                        >
                            {errors[model]?.message}
                        </div>
                    )}
                </span>
            </span>
        )
    );
};

PrimeInputTextarea.propTypes = {
    /** Determines if the component is hidden or shown */
    showif: PropTypes.bool,
    /** Accepts a Content Manager key and assigns the value to the label of the input */
    label: PropTypes.string,
    labelKey: PropTypes.string,
    /** List of CSS classnames to apply on label element  */
    labelClassName: PropTypes.string,
    /** Prop that automatically capitalizes entered text */
    autoCapitalize: PropTypes.bool,
    /** Helper Text via Label Key for locale compatibility */
    helperTextLabel: PropTypes.string,
    helperTextLabelKey: PropTypes.string,
    /** Helper text class name */
    helperTextClassName: PropTypes.string,
    /** Determines if helper text is hidden or shown */
    helperTextShowIf: PropTypes.bool,
    /** Determines if an input is required for Form validation */
    calculateLength: PropTypes.func,
    /** Determines if component truncates text to max length based on result returned by custom calculateLength function */
    truncate: PropTypes.bool,
    /** Determine whether characters remaining count will show */
    showRemaining: PropTypes.bool,
    /** Determine whether how many characters entered count will show  */
    showCurrent: PropTypes.bool,
    /** Characters Remaining WcmKey */
    charRemainingKey: PropTypes.string,
    /** Characters Entered WcmKey */
    charEnteredKey: PropTypes.string,
    /** Additional classes to add to the characters remaining text */
    charRemainingClass: PropTypes.string,
    /** Additional classes to add to the characters entered text */
    charEnteredClass: PropTypes.string,
    /** Input max length */
    maxLength: PropTypes.number,
};

PrimeInputTextarea.defaultProps = {
    autoCapitalize: false,
    calculateLength: (str) => str.length,
    showRemaining: false,
    showCurrent: false,
    truncate: false,
    maxLength: 100, // You can define default maxLength if needed
};

export default PrimeWrapper(PrimeInputTextarea);
Leave a Comment