@navinc/base-react-components
Version:
Nav's Pattern Library
89 lines • 7.08 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Button } from '../button/button.js';
import { IconButton } from '../icon-button/icon-button.js';
import { Icon } from '../icon/icon.js';
import { useState, useRef, useEffect } from 'react';
const PromptLibrarySection = ({ title, prompts, onSelect }) => {
const promptArray = Array.isArray(prompts) ? prompts : [prompts];
return (_jsxs("div", { className: "flex flex-col w-full px-300 pb-300 gap-200", children: [_jsx("p", { className: "text-headline", children: title }), _jsx("div", { className: "grid grid-cols-1 tablet:grid-cols-2 gap-200", children: promptArray.map((promptText, index) => (_jsx(Button, { onClick: () => onSelect(promptText), className: "flex w-full h-fit text-left", children: _jsxs("div", { className: "flex w-full justify-between items-end self-start gap-25 rounded-200", children: [_jsx("p", { className: "break-words body2-emphasized", children: promptText }), _jsx(Icon, { size: "medium", name: "arrow_forward", className: "text-onSurfaceVariant shrink-0" })] }) }, index))) })] }));
};
export const NaviChat = (_a) => {
var { shouldShowChat = false, promptLibrary, onPromptSelect, onPromptLibraryToggle, isPromptLibraryOpen = false } = _a, props = __rest(_a, ["shouldShowChat", "promptLibrary", "onPromptSelect", "onPromptLibraryToggle", "isPromptLibraryOpen"]);
const [isDrawerVisible, setIsDrawerVisible] = useState(false);
const [drawerBottom, setDrawerBottom] = useState(0);
const [inputText, setInputText] = useState('');
const textareaRef = useRef(null);
const inputRef = useRef(null);
const drawerRef = useRef(null);
const promptLibraryArray = Array.isArray(promptLibrary) ? promptLibrary : [promptLibrary];
// Add this effect to sync with the isPromptLibraryOpen prop
useEffect(() => {
setIsDrawerVisible(isPromptLibraryOpen);
}, [isPromptLibraryOpen]);
useEffect(() => {
if (isDrawerVisible && inputRef.current) {
const height = inputRef.current.getBoundingClientRect().height;
setDrawerBottom(height - 8); // 16px margin between drawer and input
}
}, [isDrawerVisible]);
const toggleDrawer = (event) => {
event.stopPropagation(); // Prevent click from immediately closing drawer
setIsDrawerVisible(!isDrawerVisible);
onPromptLibraryToggle === null || onPromptLibraryToggle === void 0 ? void 0 : onPromptLibraryToggle(!isDrawerVisible);
};
const handleInput = () => {
if (textareaRef.current) {
setInputText(textareaRef.current.value);
}
const textarea = textareaRef.current;
if (textarea) {
textarea.style.height = 'auto';
textarea.style.height = `${textarea.scrollHeight}px`;
}
};
const handlePromptClick = (promptText) => {
if (onPromptSelect) {
onPromptSelect(promptText); // This ensures the text gets passed to the parent
}
setIsDrawerVisible(false);
};
const handleSubmit = () => {
if (textareaRef.current && inputText) {
onPromptSelect === null || onPromptSelect === void 0 ? void 0 : onPromptSelect(inputText);
textareaRef.current.value = '';
textareaRef.current.style.height = 'auto';
setInputText('');
}
};
// This effect handles closing the drawer when clicking outside of it
useEffect(() => {
const handleClickOutside = (event) => {
if (drawerRef.current && !drawerRef.current.contains(event.target)) {
setIsDrawerVisible(false);
}
};
if (isDrawerVisible) {
document.addEventListener('click', handleClickOutside);
}
return () => document.removeEventListener('click', handleClickOutside);
// eslint-disable-next-line react-hooks/exhaustive-deps -- we only want to run this when the drawer is open
}, [isDrawerVisible]);
return (_jsx("div", Object.assign({ ref: inputRef, className: "shadow-md fixed bottom-500 flex w-full items-center justify-center px-100 pb-50 z-30" }, props, { children: _jsxs("div", { className: "relative flex w-full max-w-[600px] flex-col items-start justify-center rounded-400 bg-surfaceContainerLowest shadow-elevation3", children: [_jsx("div", { className: "flex w-full items-center gap-100 p-75", children: shouldShowChat && (_jsx("textarea", { disabled: !shouldShowChat, ref: textareaRef, placeholder: "Ask about your business...", className: "max-h-[120px] p-75 min-h-300 w-full resize-none overflow-hidden bg-transparent text-title3 text-onSurfaceDim outline-none", rows: 1, onInput: handleInput })) }), _jsxs("div", { className: "flex w-full gap-100 px-150 pb-150 justify-between tablet:flex-row tablet:items-center ", children: [_jsxs("div", { className: "flex gap-100 tablet:flex-row tablet:flex-[1_0_0] tablet:items-center", children: [_jsxs(Button, { disabled: true, children: [_jsx(Icon, { name: "support_agent" }), "Contact Support"] }), _jsxs(Button, { onClick: toggleDrawer, "data-testid": "prompt-library-drawer", children: [_jsx(Icon, { name: "library_books" }), "Prompt Library"] }), _jsxs("div", { ref: drawerRef, className: `absolute left-1/2 -translate-x-1/2 flex flex-col w-[96%] max-w-[600px] max-h-[80vh] rounded-t-400 bg-surfaceContainerHigh shadow-elevation3
-z-10 ${isDrawerVisible ? 'animate-drawer-in' : 'animate-drawer-out'} ${!isDrawerVisible && 'pointer-events-none'}
`, style: {
bottom: `${drawerBottom}px`,
visibility: isDrawerVisible ? 'visible' : 'hidden',
}, children: [_jsxs("div", { className: "flex w-full px-300 py-200 items-center justify-between", children: [_jsx("p", { className: "title3-emphasized", children: "Prompt Library" }), _jsx(IconButton, { name: "expand_more", size: "large", onClick: toggleDrawer })] }), _jsx("div", { className: "overflow-y-auto", children: promptLibraryArray.map((promptLibrary, index) => (_jsx(PromptLibrarySection, { onSelect: handlePromptClick, title: promptLibrary.title, prompts: promptLibrary.prompts }, index))) })] }), _jsx(IconButton, { name: "history", size: "large", className: "shadow-elevation1", disabled: true })] }), _jsx(IconButton, { name: `${!inputText ? 'graphic_eq' : 'arrow_upward'}`, size: "large", className: "shadow-elevation1", disabled: !shouldShowChat, onClick: handleSubmit })] })] }) })));
};
//# sourceMappingURL=navi-chat.js.map