Welcome to the Chat Widget Demo!

A lightweight, framework-free chat widget designed to integrate seamlessly with any web page. This widget allows easy connectivity to multiple data sources and can be embedded into store pages with minimal setup. Developers only need to reference the built JavaScript and CSS files in their project.

Online demo: https://hp-chat-widget.netlify.app
GitHub: https://github.com/ardeshirvalipoor/chat
Figma: https://www.figma.com/design/dUIseUd5WFlL6hwR7hVD72/HelloPrint

๐Ÿš€ Why This Approach?

We built this widget without using any UI framework to ensure:

โœจ Features

๐Ÿ“ฆ Installation

To get started, clone the repository and install dependencies:

 git clone https://github.com/ardeshirvalipoor/chat.git
     cd chat-widget
     npm install
    

To build the project:

npm run build
    

๐Ÿ“œ Usage

Include in HTML

Simply reference the built JS and CSS files:

<link rel="stylesheet" href="chat-widget.css">
    <script src="chat-widget.js"></script>
    

๐Ÿ—๏ธ Widget Structure

The widget is built around a Base function that creates DOM elements wrapped in an object.

Component Interface

export interface Component {
        el: HTMLElement;
        append(child: Component): Component;
        text(content: string): Component;
        cssClass(cls: string): Component;
        on(event: string, listener: Function): void;
        emit(event: string, ...args: any[]): void;
    }
    

Base Function

import { EventEmitter } from "./event-emitter";
    
    export function Base(tag: string = 'div'): Component {
        const el = document.createElement(tag);
        const emitter = new EventEmitter();
    
        return {
            el,
            append(child: any) {
                if (child && child.el instanceof HTMLElement) {
                    el.appendChild(child.el);
                }
                return this;
            },
            text(content: string) {
                el.textContent = content;
                return this;
            },
            cssClass(cls: string) {
                el.classList.add(cls);
                return this;
            },
            ...{
                on: emitter.on.bind(emitter),
                emit: emitter.emit.bind(emitter),
            },
        };
    }
    

Event System (EventEmitter)

export class EventEmitter {
        private events: Record<string, Function[]> = {};
    
        on(event: string, listener: Function) {
            (this.events[event] ||= []).push(listener);
            return this;
        }
    
        off(event: string, listener: Function) {
            if (!this.events[event]) return;
            this.events[event] = this.events[event].filter(l => l !== listener);
        }
    
        emit(event: string, ...args: any[]) {
            (this.events[event] || []).forEach(listener => listener(...args));
        }
    }
    
    export const globalEmitter = new EventEmitter();
    

Example Chat Component

import { Base } from "../../lib/component";
    import { globalEmitter } from "../../lib/event-emitter";
    import { Sample } from "../sample/sample";
    import { Title } from "../title/title";
    import styles from './chat.module.css';
    
    export function Chat() {
        const base = Base().cssClass(styles.base);
    
        const title = Title('Chat');
        title.on('title', (data: string) => {
            console.log(data);
        });
        base.append(title);
    
        const sample = Sample();
        base.append(sample);
    
        globalEmitter.on('sample', (data: string) => {
            sample.text(data);
        });
    
        return base;
    }
    

Adding TalkJS

follow the instructions on the TalkJS website to add a 1-on-1 chat to the widget.