@servicetitan/assist-ui
Version:
ServiceTitan Atlas UI Components
126 lines (125 loc) • 5.75 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import { Button, Menu } from '@servicetitan/anvil2';
import IconPlus from '@servicetitan/anvil2/assets/icons/material/round/add.svg';
import IconMic from '@servicetitan/anvil2/assets/icons/material/round/mic.svg';
import IconSend from '@servicetitan/anvil2/assets/icons/material/round/send.svg';
import IconAttachFile from '@servicetitan/anvil2/assets/icons/st/attach_file.svg';
import * as styles from './chat-composer-rich.module.less';
export const ChatComposerRich = ({ message, onSend, onChange, placeholder = 'Ask anything...', disabled = false, className, onUploadFile, onDictateMessage, messageInputId, sendIconId })=>{
const [isEmpty, setIsEmpty] = useState(true);
const editorRef = useRef(null);
useEffect(()=>{
if (editorRef.current && message) {
editorRef.current.innerText = message;
}
}, [
message
]);
const handleInput = ()=>{
var _editorRef_current;
var _editorRef_current_innerText_trim;
const text = (_editorRef_current_innerText_trim = (_editorRef_current = editorRef.current) === null || _editorRef_current === void 0 ? void 0 : _editorRef_current.innerText.trim()) !== null && _editorRef_current_innerText_trim !== void 0 ? _editorRef_current_innerText_trim : '';
setIsEmpty(text.length === 0);
};
const handleKeyDown = (e)=>{
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSubmit();
}
};
const handleSubmit = ()=>{
var _editorRef_current;
if (disabled) {
return;
}
var _editorRef_current_innerText_trim;
const text = (_editorRef_current_innerText_trim = (_editorRef_current = editorRef.current) === null || _editorRef_current === void 0 ? void 0 : _editorRef_current.innerText.trim()) !== null && _editorRef_current_innerText_trim !== void 0 ? _editorRef_current_innerText_trim : '';
onChange(text);
if (!text) {
return;
}
onSend === null || onSend === void 0 ? void 0 : onSend(text);
if (editorRef.current) {
// Clear content while preserving the element structure
editorRef.current.innerText = '';
// Force a reflow to ensure styles are reapplied
}
setIsEmpty(true);
};
useEffect(()=>{
var _editorRef_current;
// Ensure empty placeholder is visible on mount
setIsEmpty(!((_editorRef_current = editorRef.current) === null || _editorRef_current === void 0 ? void 0 : _editorRef_current.innerText.trim()));
}, []);
return /*#__PURE__*/ _jsx("div", {
className: classNames(styles.composerWrapper, className),
children: /*#__PURE__*/ _jsxs("form", {
onSubmit: (e)=>e.preventDefault(),
className: classNames(styles.composerForm, {
[styles.disabled]: disabled
}),
children: [
onDictateMessage || onUploadFile ? /*#__PURE__*/ _jsxs(Menu, {
id: "",
trigger: (props)=>/*#__PURE__*/ _jsx(Button, {
...props,
type: "button",
"aria-label": "Open menu",
disabled: disabled,
className: styles.iconButton,
icon: IconPlus,
size: "small"
}),
disabled: disabled,
children: [
/*#__PURE__*/ _jsx(Menu.Item, {
label: "Upload file",
icon: IconAttachFile,
onClick: onUploadFile
}),
/*#__PURE__*/ _jsx(Menu.Item, {
label: "Dictate message",
icon: IconMic,
onClick: onDictateMessage
})
]
}) : /*#__PURE__*/ _jsx("div", {}),
/*#__PURE__*/ _jsxs("div", {
className: styles.inputWrapper,
children: [
/*#__PURE__*/ _jsx("div", {
id: messageInputId,
ref: editorRef,
contentEditable: !disabled ? 'plaintext-only' : false,
role: "textbox",
"aria-multiline": "true",
"aria-label": placeholder,
"data-placeholder": placeholder,
onInput: handleInput,
onKeyDown: handleKeyDown,
className: styles.input
}),
isEmpty && /*#__PURE__*/ _jsx("span", {
className: styles.placeholder,
children: placeholder
})
]
}),
/*#__PURE__*/ _jsx(Button, {
id: sendIconId,
size: "small",
type: "button",
onClick: handleSubmit,
disabled: disabled || isEmpty,
className: styles.sendButton,
"aria-label": "Send message",
appearance: "ghost",
icon: IconSend
})
]
})
});
};
//# sourceMappingURL=chat-composer-rich.js.map