customElements.define(
"chat-app",
class extends HTMLElement {
connectedCallback() {
if (!this.isConnected) return;
const form = window.querySelectorExt(
this,
"find form",
) as HTMLFormElement;
const messageInput = (
form.elements as unknown as { message: HTMLInputElement }
).message;
const messageArea = window.querySelectorExt(
this,
"find .chat-messages",
) as Element;
// Handle form submissions
form.addEventListener("submit", (event) => {
const message = messageInput.value.trim();
// Show a validation message if the input is empty
if (!message) {
messageInput.setCustomValidity("Please provide a message.");
// Prevent the form from submitting
event.preventDefault();
return;
}
// Create a new message element
const msg = document.createElement("div");
msg.className = "message user-message";
msg.innerHTML = `
${message}
`; // Insert the message before the pending AI message messageArea.insertBefore( msg, messageArea.querySelector(".pending-ai-message"), ); setTimeout(() => { messageInput.value = ""; messageArea.scrollTop = messageArea.scrollHeight; }); }); // Focus on the input field after the message is processed form.addEventListener("htmx:afterSettle", () => { messageInput.focus(); }); // Monitor the previousElementSibling for changes. If it's already scrolled down, // scroll down to the new message. Otherwise, leave it alone. let timeout: ReturnType