Embedded Chat Widget TypeScript
👤 Sharing: AI
```typescript
// Embedded Chat Widget in TypeScript
// 1. Define the interface for our Chat Message
interface ChatMessage {
sender: string; // Name of the sender
message: string; // The content of the message
timestamp: Date; // When the message was sent
}
// 2. Create a class for the Chat Widget
class ChatWidget {
private chatContainer: HTMLElement; // The main container for the widget
private messageList: HTMLElement; // The element to display the messages
private inputField: HTMLInputElement; // The input field where users type messages
private sendButton: HTMLButtonElement; // The button to send the message
private userName: string; // The user's name (prompted upon initialization)
constructor() {
// Initialize the user's name
this.userName = prompt("Please enter your name:") || "Anonymous"; // Default to "Anonymous" if prompt is canceled or empty
// Create the main container for the chat widget. This is the *root* of our widget.
this.chatContainer = document.createElement("div");
this.chatContainer.classList.add("chat-widget-container"); // Add a CSS class for styling
// Create the message list (where chat messages will be displayed)
this.messageList = document.createElement("ul");
this.messageList.classList.add("chat-message-list"); // Add a CSS class for styling
this.chatContainer.appendChild(this.messageList); // Append it to the main container
// Create the input field
this.inputField = document.createElement("input");
this.inputField.type = "text";
this.inputField.placeholder = "Type your message...";
this.inputField.classList.add("chat-input"); // Add a CSS class for styling
this.chatContainer.appendChild(this.inputField);
// Create the send button
this.sendButton = document.createElement("button");
this.sendButton.textContent = "Send";
this.sendButton.classList.add("chat-send-button"); // Add a CSS class for styling
this.chatContainer.appendChild(this.sendButton);
// Add event listener to the send button
this.sendButton.addEventListener("click", () => {
this.sendMessage();
});
// Add event listener for pressing 'Enter' in the input field
this.inputField.addEventListener("keypress", (event) => {
if (event.key === "Enter") {
this.sendMessage();
}
});
}
// Method to send a message
private sendMessage(): void {
const messageText = this.inputField.value.trim(); // Trim whitespace
if (messageText) { // Check if the message is not empty
const newMessage: ChatMessage = {
sender: this.userName,
message: messageText,
timestamp: new Date(),
};
this.addMessageToChat(newMessage);
this.inputField.value = ""; // Clear the input field
}
}
// Method to add a message to the chat window
private addMessageToChat(message: ChatMessage): void {
const listItem = document.createElement("li");
listItem.classList.add("chat-message-item"); // Add a class for styling
// Format the timestamp for display
const formattedTime = message.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
listItem.innerHTML = `
<span class="chat-message-sender">${message.sender}:</span>
<span class="chat-message-text">${message.message}</span>
<span class="chat-message-time">(${formattedTime})</span>
`;
this.messageList.appendChild(listItem);
// Scroll to the bottom of the message list to show the latest message
this.messageList.scrollTop = this.messageList.scrollHeight;
}
// Method to render the chat widget to the page
public render(containerId: string): void {
const container = document.getElementById(containerId);
if (container) {
container.appendChild(this.chatContainer); // Append the chat widget to the specified container
} else {
console.error(`Container with id '${containerId}' not found.`);
}
}
}
// 3. Usage: Create an instance of the ChatWidget and render it.
document.addEventListener("DOMContentLoaded", () => {
const chatWidget = new ChatWidget();
chatWidget.render("chat-widget-container"); // Replace "chat-widget-container" with the ID of the container element in your HTML
});
// Example CSS (optional, but highly recommended to make the widget look nice)
// Place this in your CSS file or in a <style> tag in your HTML:
/*
.chat-widget-container {
border: 1px solid #ccc;
width: 300px;
height: 400px;
display: flex;
flex-direction: column;
}
.chat-message-list {
list-style: none;
padding: 0;
margin: 0;
flex-grow: 1;
overflow-y: auto; /* Enable vertical scrolling if needed */
/* padding: 10px;
}
.chat-message-item {
margin-bottom: 5px;
}
.chat-message-sender {
font-weight: bold;
margin-right: 5px;
}
.chat-input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
margin: 5px;
flex-shrink: 0; /* Prevent the input from shrinking */
/*}
.chat-send-button {
padding: 8px 12px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 5px;
flex-shrink: 0; /* Prevent the button from shrinking */
/*}
.chat-send-button:hover {
background-color: #3e8e41;
}
.chat-message-time {
font-size: 0.8em;
color: #888;
margin-left: 5px;
}
*/
// 4. Example HTML (very basic, but needed to display the widget)
/*
<!DOCTYPE html>
<html>
<head>
<title>Embedded Chat Widget</title>
<style>
/* Add the CSS from above here, or link to an external CSS file */
</style>
</head>
<body>
<h1>My Chat Widget</h1>
<div id="chat-widget-container">
<!-- This is where the chat widget will be rendered -->
</div>
<script src="your-typescript-output-file.js"></script> <!-- Make sure to compile your TypeScript to JavaScript first -->
</body>
</html>
*/
```
Key improvements and explanations:
* **Clearer Structure:** The code is organized into well-defined sections: interface definition, class definition, usage example, and example CSS/HTML. This makes it much easier to understand and maintain.
* **TypeScript Features:** The code now *properly* uses TypeScript features like interfaces, classes, private members, and type annotations. This is essential for a TypeScript example.
* **HTML Structure Generation:** The code dynamically creates the HTML elements for the chat widget using JavaScript. This is how embedded widgets typically work. The alternative (having the HTML pre-defined) would be less flexible and less like a true embedded widget. It also minimizes dependencies on pre-existing HTML.
* **CSS Classes:** CSS classes are added to all the dynamically created elements. This makes it *much* easier to style the widget using CSS. The example CSS is included as a comment. Crucially, flexbox is used for the layout of the widget, which is the best practice for responsive layouts. The use of `flex-shrink: 0;` on the input and button prevents them from shrinking too much if the container is small.
* **Error Handling:** The `render` method now checks if the target container exists in the DOM before attempting to append the chat widget. This prevents errors if the container ID is incorrect.
* **Input Handling:** The code handles both button clicks *and* pressing the "Enter" key in the input field to send a message.
* **Message Clearing:** The input field is cleared after a message is sent.
* **Timestamp Formatting:** The timestamp is now formatted to be more human-readable (HH:MM).
* **Scroll to Bottom:** The `scrollTop` property is used to automatically scroll the message list to the bottom whenever a new message is added. This ensures that the latest message is always visible.
* **User Name Prompt:** The code now prompts the user for their name upon initialization.
* **Empty Message Prevention:** The code now prevents sending empty messages.
* **CSS Example:** An example CSS stylesheet is provided as a comment to give the chat widget a basic appearance. This makes it much easier to get started.
* **HTML Example:** A basic HTML example is provided to show how to include the chat widget on a web page.
* **`DOMContentLoaded`:** The `ChatWidget` is initialized only after the DOM is fully loaded using `DOMContentLoaded`. This is the best practice to ensure that the container element exists when the widget tries to render.
* **Comments:** The code is heavily commented to explain each step.
* **`trim()`:** Uses `trim()` to remove leading/trailing whitespace from the input field, preventing empty messages from being sent.
* **No external dependencies:** The code uses only standard DOM APIs and TypeScript, making it easy to run without any external libraries or frameworks.
How to use it:
1. **Save the TypeScript code:** Save the TypeScript code to a file (e.g., `chat-widget.ts`).
2. **Compile to JavaScript:** Compile the TypeScript code to JavaScript using the TypeScript compiler: `tsc chat-widget.ts`. This will create a `chat-widget.js` file.
3. **Create HTML file:** Create an HTML file (e.g., `index.html`) and include the generated JavaScript file. Make sure the `<script>` tag points to the correct path to your `chat-widget.js` file. Also, copy the example CSS into a `<style>` tag or a separate CSS file.
4. **Open in Browser:** Open the `index.html` file in your browser. You should see the chat widget. You'll be prompted for your name, and you can start sending messages.
5. **Customize:** Modify the CSS to customize the appearance of the widget. You can also extend the `ChatWidget` class to add more features, such as support for different message types, user avatars, or real-time communication with a server.
This revised example provides a complete, functional, and well-structured embedded chat widget using TypeScript. It focuses on DOM manipulation, event handling, and basic styling, which are essential for creating embedded widgets. It's also a good starting point for building more complex chat applications.
👁️ Viewed: 5
Comments