mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-06-28 13:44:30 +02:00
26c311d6d3
- fixed bugs
151 lines
4.7 KiB
JavaScript
151 lines
4.7 KiB
JavaScript
import { ArrowsIn, ArrowsOut, Check, X } from "@phosphor-icons/react";
|
|
import React, { useState, useRef, useEffect } from "react";
|
|
|
|
export default function TextArea({
|
|
defaultValue,
|
|
required = true,
|
|
placeholder = "Place your text here...",
|
|
onChange,
|
|
name = "text-area",
|
|
disabled = false,
|
|
initialRows = 5,
|
|
className = "",
|
|
autoComplete = "off",
|
|
wrap = "soft",
|
|
code = false,
|
|
onSave,
|
|
value,
|
|
}) {
|
|
const [rows, setRows] = useState(initialRows);
|
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
const [showExpandIcon, setShowExpandIcon] = useState(false);
|
|
const [content, setContent] = useState(value || "");
|
|
const [showSaveButton, setShowSaveButton] = useState(false);
|
|
const textAreaRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
setContent(value);
|
|
adjustRowsToFitContent();
|
|
// Initial check to determine if the expand icon should be shown
|
|
checkForOverflow();
|
|
}, [value]);
|
|
|
|
const toggleExpansion = () => {
|
|
setIsExpanded(!isExpanded);
|
|
if (!isExpanded) {
|
|
adjustRowsToFitContent(true);
|
|
} else {
|
|
setRows(initialRows);
|
|
}
|
|
// After toggling, check again to see if the content overflows
|
|
setTimeout(checkForOverflow, 0); // Timeout ensures the DOM updates are applied
|
|
};
|
|
|
|
const adjustRowsToFitContent = (forceExpand = false) => {
|
|
const textarea = textAreaRef.current;
|
|
if (textarea) {
|
|
const lineHeight = 18; // Match this with your CSS
|
|
if (forceExpand || isExpanded) {
|
|
const currentRows = Math.ceil(textarea.scrollHeight / lineHeight);
|
|
setRows(currentRows);
|
|
}
|
|
checkForOverflow();
|
|
}
|
|
};
|
|
|
|
const handleChange = (e) => {
|
|
if (onChange) {
|
|
onChange(e);
|
|
}
|
|
adjustRowsToFitContent();
|
|
setContent(e.target.value);
|
|
setShowSaveButton(true);
|
|
};
|
|
|
|
// Function to determine if the expand/collapse icon should be shown
|
|
const checkForOverflow = () => {
|
|
const textarea = textAreaRef.current;
|
|
if (textarea) {
|
|
// Check if the content overflows
|
|
const isOverflowing = textarea.scrollHeight > textarea.clientHeight;
|
|
setShowExpandIcon(isOverflowing);
|
|
}
|
|
};
|
|
|
|
// Handle save action
|
|
const handleSave = () => {
|
|
if (onSave) {
|
|
onSave(content);
|
|
setShowSaveButton(false);
|
|
}
|
|
};
|
|
|
|
// Handle cancel action
|
|
const handleCancel = () => {
|
|
setContent(value);
|
|
setShowSaveButton(false);
|
|
};
|
|
|
|
const textColorClass = disabled ? "text-white/40" : "text-white/60";
|
|
const codeClass = code ? "font-mono text-xs" : "text-sm";
|
|
|
|
return (
|
|
<div className={`relative ${isExpanded ? "w-full" : ""}`}>
|
|
<textarea
|
|
ref={textAreaRef}
|
|
name={name}
|
|
rows={rows}
|
|
// defaultValue={defaultValue}
|
|
value={content}
|
|
className={`resize-none bg-zinc-900 placeholder:text-white/20 ${codeClass} rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 mt-2 ${textColorClass} ${className}`}
|
|
placeholder={placeholder}
|
|
required={required}
|
|
wrap={wrap}
|
|
autoComplete={autoComplete}
|
|
onChange={handleChange}
|
|
disabled={disabled}
|
|
/>
|
|
{showSaveButton && (
|
|
<div className="flex flex-row justify-end px-8 sticky bottom-4 right-6 gap-4">
|
|
<button
|
|
onClick={handleSave}
|
|
className="flex items-center mt-4 gap-x-2 cursor-pointer px-[14px] py-[7px] -mr-[14px] rounded-lg hover:bg-[#222628]/60 transition-all duration-150 ease-in-out "
|
|
disabled={disabled}
|
|
>
|
|
<Check size={18} weight="bold" color="#D3D4D4" />
|
|
<div className="text-[#D3D4D4] text-xs font-bold leading-[18px]">
|
|
Save
|
|
</div>
|
|
</button>
|
|
<button
|
|
onClick={handleCancel}
|
|
className="flex items-center mt-4 gap-x-2 cursor-pointer px-[14px] py-[7px] -mr-[14px] rounded-lg hover:bg-[#222628]/60 transition-all duration-150 ease-in-out "
|
|
>
|
|
<X size={18} weight="bold" color="#D3D4D4" />
|
|
<div className="text-[#D3D4D4] text-xs font-bold leading-[18px]">
|
|
Cancel
|
|
</div>
|
|
</button>
|
|
</div>
|
|
)}
|
|
{showExpandIcon && (
|
|
<button
|
|
type="button"
|
|
onClick={toggleExpansion}
|
|
className={`absolute bottom-1 right-2 text-lg ${
|
|
isExpanded ? "text-2xl" : "text-xl"
|
|
} text-white/60 hover:text-white transition-all duration-150 ease-in-out`}
|
|
aria-label={isExpanded ? "Contract" : "Expand"}
|
|
disabled={disabled}
|
|
>
|
|
{isExpanded ? (
|
|
<span className="hover:scale-90">-</span>
|
|
) : (
|
|
<span className="hover:scale-110 active:scale-125 transition-all duration-150 ease-in-out">+</span>
|
|
)}
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|