lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
111 lines • 9.27 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AiInput = AiInput;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const framer_motion_1 = require("framer-motion");
const lucide_react_1 = require("lucide-react");
const utils_1 = require("@/components/lib/utils");
const textarea_1 = require("./textarea");
function useAutoResizeTextarea({ minHeight, maxHeight, }) {
const textareaRef = (0, react_1.useRef)(null);
const adjustHeight = (0, react_1.useCallback)((reset) => {
const textarea = textareaRef.current;
if (!textarea)
return;
if (reset) {
textarea.style.height = `${minHeight}px`;
return;
}
textarea.style.height = `${minHeight}px`;
const newHeight = Math.max(minHeight, Math.min(textarea.scrollHeight, maxHeight ?? Number.POSITIVE_INFINITY));
textarea.style.height = `${newHeight}px`;
}, [minHeight, maxHeight]);
(0, react_1.useEffect)(() => {
const textarea = textareaRef.current;
if (textarea) {
textarea.style.height = `${minHeight}px`;
}
}, [minHeight]);
(0, react_1.useEffect)(() => {
const handleResize = () => adjustHeight();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [adjustHeight]);
return { textareaRef, adjustHeight };
}
const MIN_HEIGHT = 48;
const MAX_HEIGHT = 164;
const AnimatedPlaceholder = ({ showSearch }) => ((0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", children: (0, jsx_runtime_1.jsx)(framer_motion_1.motion.p, { initial: { opacity: 0, y: 5 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -5 }, transition: { duration: 0.1 }, className: "pointer-events-none w-[1500px] text-sm absolute \r\n text-black/70 dark:text-white/70", children: showSearch ? "Search the web..." : "Ask Skiper Ai..." }, showSearch ? "search" : "ask") }));
function AiInput() {
const [value, setValue] = (0, react_1.useState)("");
const { textareaRef, adjustHeight } = useAutoResizeTextarea({
minHeight: MIN_HEIGHT,
maxHeight: MAX_HEIGHT,
});
const [showSearch, setShowSearch] = (0, react_1.useState)(true);
const [imagePreview, setImagePreview] = (0, react_1.useState)(null);
const fileInputRef = (0, react_1.useRef)(null);
const handelClose = (e) => {
e.preventDefault();
e.stopPropagation();
if (fileInputRef.current) {
fileInputRef.current.value = ""; // Reset file input
}
setImagePreview(null); // Use null instead of empty string
};
const handelChange = (e) => {
const file = e.target.files ? e.target.files[0] : null;
if (file) {
setImagePreview(URL.createObjectURL(file));
}
};
const handleSubmit = () => {
setValue("");
adjustHeight(true);
};
(0, react_1.useEffect)(() => {
return () => {
if (imagePreview) {
URL.revokeObjectURL(imagePreview);
}
};
}, [imagePreview]);
return ((0, jsx_runtime_1.jsx)("div", { className: "mx-auto lg:min-w-[400px] w-full py-4", children: (0, jsx_runtime_1.jsx)("div", { className: "relative max-w-xl border rounded-[22px] border-black/5 p-1 w-full mx-auto", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative rounded-2xl border border-black/5 bg-neutral-800/5 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { style: { maxHeight: `${MAX_HEIGHT}px` }, children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(textarea_1.Textarea, { id: "ai-input-04", value: value, placeholder: "", className: "w-full rounded-2xl rounded-b-none px-4 py-3 bg-black/5 dark:bg-white/5 border-none dark:text-white resize-none focus-visible:ring-0 leading-[1.2]", ref: textareaRef, onKeyDown: (e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmit();
}
}, onChange: (e) => {
setValue(e.target.value);
adjustHeight();
} }), !value && ((0, jsx_runtime_1.jsx)("div", { className: "absolute left-4 top-3", children: (0, jsx_runtime_1.jsx)(AnimatedPlaceholder, { showSearch: showSearch }) }))] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "h-12 bg-black/5 dark:bg-white/5 rounded-b-xl", children: [(0, jsx_runtime_1.jsxs)("div", { className: "absolute left-3 bottom-3 flex items-center gap-2", children: [(0, jsx_runtime_1.jsxs)("label", { className: (0, utils_1.cn)("cursor-pointer relative rounded-full p-2 bg-black/5 dark:bg-white/5", imagePreview
? "bg-[#ff3f17]/15 border border-[#ff3f17] text-[#ff3f17]"
: "bg-black/5 dark:bg-white/5 text-black/40 dark:text-white/40 hover:text-black dark:hover:text-white"), children: [(0, jsx_runtime_1.jsx)("input", { type: "file", ref: fileInputRef, onChange: handelChange, className: "hidden" }), (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: (0, utils_1.cn)("w-4 h-4 text-black/40 dark:text-white/40 hover:text-black dark:hover:text-white transition-colors", imagePreview && "text-[#ff3f17]") }), imagePreview && ((0, jsx_runtime_1.jsxs)("div", { className: "absolute w-[100px] h-[100px] top-14 -left-4", children: [(0, jsx_runtime_1.jsx)("img", { className: "object-cover rounded-2xl", src: imagePreview || "/picture1.jpeg", height: 500, width: 500, alt: "additional image" }), (0, jsx_runtime_1.jsx)("button", { onClick: handelClose, className: "bg-[#e8e8e8] text-[#464646] absolute -top-1 -left-1 shadow-3xl rounded-full rotate-45", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "w-4 h-4" }) })] }))] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => {
setShowSearch(!showSearch);
}, className: (0, utils_1.cn)("rounded-full transition-all flex items-center gap-2 px-1.5 py-1 border h-8", showSearch
? "bg-[#ff3f17]/15 border-[#ff3f17] text-[#ff3f17]"
: "bg-black/5 dark:bg-white/5 border-transparent text-black/40 dark:text-white/40 hover:text-black dark:hover:text-white"), children: [(0, jsx_runtime_1.jsx)("div", { className: "w-4 h-4 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { animate: {
rotate: showSearch ? 180 : 0,
scale: showSearch ? 1.1 : 1,
}, whileHover: {
rotate: showSearch ? 180 : 15,
scale: 1.1,
transition: {
type: "spring",
stiffness: 300,
damping: 10,
},
}, transition: {
type: "spring",
stiffness: 260,
damping: 25,
}, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Globe, { className: (0, utils_1.cn)("w-4 h-4", showSearch ? "text-[#ff3f17]" : "text-inherit") }) }) }), (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: showSearch && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.span, { initial: { width: 0, opacity: 0 }, animate: {
width: "auto",
opacity: 1,
}, exit: { width: 0, opacity: 0 }, transition: { duration: 0.2 }, className: "text-sm overflow-hidden whitespace-nowrap text-[#ff3f17] flex-shrink-0", children: "Search" })) })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "absolute right-3 bottom-3", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: handleSubmit, className: (0, utils_1.cn)("rounded-full p-2 transition-colors", value
? "bg-[#ff3f17]/15 text-[#ff3f17]"
: "bg-black/5 dark:bg-white/5 text-black/40 dark:text-white/40 hover:text-black dark:hover:text-white"), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Send, { className: "w-4 h-4" }) }) })] })] }) }) }));
}
//# sourceMappingURL=ai-prompt.js.map