2023-01-20 15:46:39 +00:00
|
|
|
import React, { useRef, useState, useEffect } from "react";
|
2023-12-06 12:03:40 +00:00
|
|
|
import copy from "copy-to-clipboard";
|
|
|
|
|
|
|
|
import { Toast, toastr } from "../toast";
|
|
|
|
|
2023-01-20 15:46:39 +00:00
|
|
|
import {
|
|
|
|
StyledTextarea,
|
|
|
|
StyledCopyIcon,
|
2023-06-07 17:24:46 +00:00
|
|
|
CopyIconWrapper,
|
2023-02-10 11:03:58 +00:00
|
|
|
Wrapper,
|
|
|
|
Numeration,
|
2023-12-06 12:03:40 +00:00
|
|
|
} from "./Textarea.styled";
|
|
|
|
import { isJSON, jsonify } from "./Textarea.utils";
|
|
|
|
import { TextareaProps } from "./Textarea.types";
|
|
|
|
import { TextareaTheme } from "./Textarea.theme";
|
2023-01-20 15:46:39 +00:00
|
|
|
|
2023-12-06 12:03:40 +00:00
|
|
|
const WrappedStyledCopyIcon = ({
|
|
|
|
heightScale,
|
|
|
|
isJSONField,
|
|
|
|
...props
|
|
|
|
}: TextareaProps) => <StyledCopyIcon {...props} />;
|
2023-06-07 07:33:42 +00:00
|
|
|
|
2022-05-26 11:59:09 +00:00
|
|
|
const Textarea = ({
|
|
|
|
className,
|
|
|
|
id,
|
|
|
|
isDisabled,
|
|
|
|
isReadOnly,
|
|
|
|
hasError,
|
|
|
|
heightScale,
|
|
|
|
maxLength,
|
|
|
|
name,
|
|
|
|
onChange,
|
|
|
|
placeholder,
|
|
|
|
style,
|
|
|
|
tabIndex,
|
|
|
|
value,
|
2023-12-06 12:03:40 +00:00
|
|
|
fontSize = 13,
|
2022-05-26 11:59:09 +00:00
|
|
|
heightTextArea,
|
|
|
|
color,
|
|
|
|
autoFocus,
|
|
|
|
areaSelect,
|
2023-01-20 15:46:39 +00:00
|
|
|
isJSONField,
|
|
|
|
copyInfoText,
|
2023-04-03 11:29:57 +00:00
|
|
|
enableCopy,
|
2023-03-31 14:22:29 +00:00
|
|
|
hasNumeration,
|
2023-05-01 08:27:42 +00:00
|
|
|
isFullHeight,
|
2023-12-06 12:03:40 +00:00
|
|
|
classNameCopyIcon,
|
|
|
|
}: TextareaProps) => {
|
|
|
|
const areaRef = useRef<null | HTMLTextAreaElement>(null);
|
2023-01-20 15:46:39 +00:00
|
|
|
const [isError, setIsError] = useState(hasError);
|
2023-06-07 07:33:42 +00:00
|
|
|
const modifiedValue = jsonify(value, isJSONField);
|
2023-01-20 15:46:39 +00:00
|
|
|
|
2023-02-10 11:03:58 +00:00
|
|
|
const lineHeight = 1.5;
|
|
|
|
const padding = 7;
|
2023-03-01 14:37:01 +00:00
|
|
|
const numberOfLines = modifiedValue.split("\n").length;
|
2023-03-31 14:22:29 +00:00
|
|
|
const textareaHeight = isFullHeight
|
2023-03-01 14:37:01 +00:00
|
|
|
? numberOfLines * fontSize * lineHeight + padding + 4
|
2023-02-10 11:03:58 +00:00
|
|
|
: heightTextArea;
|
|
|
|
|
2023-03-01 14:37:01 +00:00
|
|
|
const defaultPaddingLeft = 42;
|
|
|
|
const numberOfDigits =
|
|
|
|
String(numberOfLines).length - 2 > 0 ? String(numberOfLines).length : 0;
|
2023-03-31 14:22:29 +00:00
|
|
|
const paddingLeftProp = hasNumeration
|
2023-03-01 14:37:01 +00:00
|
|
|
? fontSize < 13
|
|
|
|
? `${defaultPaddingLeft + numberOfDigits * 6}px`
|
|
|
|
: `${((defaultPaddingLeft + numberOfDigits * 4) * fontSize) / 13}px`
|
|
|
|
: "8px";
|
|
|
|
|
2023-02-10 11:03:58 +00:00
|
|
|
const numerationValue = [];
|
|
|
|
|
2023-12-06 12:03:40 +00:00
|
|
|
for (let i = 1; i <= numberOfLines; i += 1) {
|
2023-02-10 11:03:58 +00:00
|
|
|
numerationValue.push(i);
|
|
|
|
}
|
|
|
|
|
2023-12-06 12:03:40 +00:00
|
|
|
const onTextareaClick = () => {
|
2023-12-19 07:40:56 +00:00
|
|
|
if (areaRef.current && enableCopy) areaRef.current.select();
|
2023-12-06 12:03:40 +00:00
|
|
|
};
|
2023-02-13 11:36:56 +00:00
|
|
|
|
2023-06-21 12:05:10 +00:00
|
|
|
useEffect(() => {
|
2023-12-06 12:03:40 +00:00
|
|
|
if (hasError !== isError) setIsError(hasError);
|
|
|
|
}, [hasError, isError]);
|
2023-06-21 12:05:10 +00:00
|
|
|
|
2023-01-20 15:46:39 +00:00
|
|
|
useEffect(() => {
|
2023-06-07 17:24:46 +00:00
|
|
|
setIsError(isJSONField && (!value || !isJSON(value)));
|
2023-06-07 12:29:59 +00:00
|
|
|
}, [isJSONField, value]);
|
2021-03-11 11:50:58 +00:00
|
|
|
|
2023-01-20 15:46:39 +00:00
|
|
|
useEffect(() => {
|
2022-05-26 11:59:09 +00:00
|
|
|
if (areaSelect && areaRef.current) {
|
|
|
|
areaRef.current.select();
|
|
|
|
}
|
2022-06-01 07:19:29 +00:00
|
|
|
}, [areaSelect]);
|
2022-05-26 11:59:09 +00:00
|
|
|
|
|
|
|
return (
|
2023-02-13 11:36:56 +00:00
|
|
|
<Wrapper
|
2023-04-18 17:38:46 +00:00
|
|
|
className="textarea-wrapper"
|
2023-02-13 11:36:56 +00:00
|
|
|
isJSONField={isJSONField}
|
2023-11-08 14:19:14 +00:00
|
|
|
enableCopy={enableCopy}
|
2023-11-21 19:04:13 +00:00
|
|
|
onClick={onTextareaClick}
|
2023-12-06 12:03:40 +00:00
|
|
|
data-testid="textarea"
|
2023-02-13 11:36:56 +00:00
|
|
|
>
|
2023-11-08 14:19:14 +00:00
|
|
|
{enableCopy && (
|
2023-06-07 17:24:46 +00:00
|
|
|
<CopyIconWrapper
|
2023-06-30 09:55:31 +00:00
|
|
|
className={classNameCopyIcon}
|
2023-12-06 12:03:40 +00:00
|
|
|
isJSONField={isJSONField || false}
|
2023-01-22 11:45:41 +00:00
|
|
|
onClick={() => {
|
|
|
|
copy(modifiedValue);
|
2023-12-06 12:03:40 +00:00
|
|
|
|
2023-01-22 11:45:41 +00:00
|
|
|
toastr.success(copyInfoText);
|
|
|
|
}}
|
2023-06-07 17:24:46 +00:00
|
|
|
>
|
|
|
|
<WrappedStyledCopyIcon heightScale={heightScale} />
|
|
|
|
</CopyIconWrapper>
|
2023-01-20 15:46:39 +00:00
|
|
|
)}
|
2023-12-06 12:03:40 +00:00
|
|
|
|
|
|
|
<TextareaTheme
|
2023-02-10 11:03:58 +00:00
|
|
|
className={className}
|
|
|
|
style={style}
|
2019-12-17 10:49:53 +00:00
|
|
|
isDisabled={isDisabled}
|
2023-02-10 11:03:58 +00:00
|
|
|
hasError={isError}
|
|
|
|
heightScale={heightScale}
|
2023-12-28 08:46:16 +00:00
|
|
|
heightTextAreaProp={textareaHeight}
|
2023-02-10 11:03:58 +00:00
|
|
|
>
|
|
|
|
<Toast />
|
|
|
|
|
2023-03-31 14:22:29 +00:00
|
|
|
{hasNumeration && (
|
2023-12-06 12:03:40 +00:00
|
|
|
<Numeration fontSize={`${fontSize}px`}>
|
2023-03-01 14:50:54 +00:00
|
|
|
{numerationValue.join("\n")}
|
|
|
|
</Numeration>
|
|
|
|
)}
|
2023-02-10 11:03:58 +00:00
|
|
|
<StyledTextarea
|
2023-12-28 08:46:16 +00:00
|
|
|
heightTextAreaProp={textareaHeight}
|
2023-02-10 11:03:58 +00:00
|
|
|
id={id}
|
2023-03-24 12:50:41 +00:00
|
|
|
paddingLeftProp={paddingLeftProp}
|
2023-02-13 11:36:56 +00:00
|
|
|
isJSONField={isJSONField}
|
2023-04-03 11:29:57 +00:00
|
|
|
enableCopy={enableCopy}
|
2023-07-07 09:47:11 +00:00
|
|
|
placeholder={placeholder}
|
2023-12-06 12:03:40 +00:00
|
|
|
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
|
|
|
|
onChange?.(e)
|
|
|
|
}
|
2023-02-10 11:03:58 +00:00
|
|
|
maxLength={maxLength}
|
|
|
|
name={name}
|
|
|
|
tabIndex={tabIndex}
|
|
|
|
isDisabled={isDisabled}
|
2023-12-06 12:03:40 +00:00
|
|
|
disabled={isDisabled || false}
|
|
|
|
readOnly={isReadOnly || false}
|
2023-02-10 11:03:58 +00:00
|
|
|
value={isJSONField ? modifiedValue : value}
|
|
|
|
fontSize={fontSize}
|
|
|
|
color={color}
|
|
|
|
autoFocus={autoFocus}
|
|
|
|
ref={areaRef}
|
2023-06-26 11:01:08 +00:00
|
|
|
dir="auto"
|
2023-02-10 11:03:58 +00:00
|
|
|
/>
|
2023-12-06 12:03:40 +00:00
|
|
|
</TextareaTheme>
|
2023-02-10 11:03:58 +00:00
|
|
|
</Wrapper>
|
2022-05-26 11:59:09 +00:00
|
|
|
);
|
|
|
|
};
|
2019-07-29 16:42:44 +00:00
|
|
|
|
2019-08-06 13:36:41 +00:00
|
|
|
Textarea.defaultProps = {
|
2019-07-31 12:44:48 +00:00
|
|
|
isDisabled: false,
|
|
|
|
isReadOnly: false,
|
2020-07-08 13:57:34 +00:00
|
|
|
hasError: false,
|
2020-07-13 11:15:44 +00:00
|
|
|
heightScale: false,
|
2023-07-07 09:47:11 +00:00
|
|
|
placeholder: " ",
|
2019-07-31 12:44:48 +00:00
|
|
|
tabIndex: -1,
|
2020-10-16 13:16:01 +00:00
|
|
|
value: "",
|
2022-05-20 11:07:46 +00:00
|
|
|
isAutoFocussed: false,
|
2022-05-26 11:59:09 +00:00
|
|
|
areaSelect: false,
|
2023-01-20 15:46:39 +00:00
|
|
|
isJSONField: false,
|
|
|
|
copyInfoText: "Content was copied successfully!",
|
2023-04-03 11:29:57 +00:00
|
|
|
enableCopy: false,
|
2023-03-31 14:22:29 +00:00
|
|
|
hasNumeration: false,
|
|
|
|
isFullHeight: false,
|
2020-10-16 13:16:01 +00:00
|
|
|
};
|
2019-07-29 16:42:44 +00:00
|
|
|
|
2023-12-06 12:03:40 +00:00
|
|
|
export { Textarea };
|