xref: /plugin/aichat/script/AIChatButton.js (revision ca3451493ff9ba1842fb5647bb2e9cb15f958c9e)
1class AIChatButton extends HTMLElement {
2    #root = null;
3    #dialog = null;
4
5
6    constructor() {
7        super();
8        this.#root = this.attachShadow({mode: 'open'});
9        this.#root.innerHTML = `
10            <button>
11                <svg viewBox="0 0 24 24"><path d="M12,3C17.5,3 22,6.58 22,11C22,15.42 17.5,19 12,19C10.76,19 9.57,18.82 8.47,18.5C5.55,21 2,21 2,21C4.33,18.67 4.7,17.1 4.75,16.5C3.05,15.07 2,13.13 2,11C2,6.58 6.5,3 12,3Z" /></svg>
12            </button>
13            <dialog>
14                <div>
15                    <header>
16                        <button>
17                            <svg viewBox="0 0 24 24"><path d="M13.46,12L19,17.54V19H17.54L12,13.46L6.46,19H5V17.54L10.54,12L5,6.46V5H6.46L12,10.54L17.54,5H19V6.46L13.46,12Z" /></svg>
18                        </button>
19                    </header>
20                    <main>
21                        <slot></slot>
22                    </main>
23                </div>
24            </dialog>
25        `;
26
27        this.#root.appendChild(this.getStyle());
28        this.#dialog = this.#root.querySelector('dialog');
29
30        const buttons = this.#root.querySelectorAll('button');
31        buttons.forEach(function (button) {
32            button.addEventListener('click', this.toggleDialog.bind(this))
33        }.bind(this));
34    }
35
36    /**
37     * Define the web component's internal styles
38     *
39     * @returns {HTMLStyleElement}
40     */
41    getStyle() {
42        const style = document.createElement('style');
43        style.textContent = `
44            :host {
45                --color-chat-icon: #4881bf;
46            }
47            button {
48                background: none;
49                border: none;
50                cursor: pointer;
51            }
52            :host > button svg {
53                fill: var(--color-chat-icon);
54            }
55            svg {
56                width: 2em;
57                height: 2em;
58
59            }
60            dialog {
61                width: 500px;
62                max-width: 90vw;
63                height: 800px;
64                max-height: 90vh;
65
66                position: fixed;
67                top: 1em;
68                right: 1em;
69                left: auto;
70
71                padding: 0.25em;
72
73                box-shadow: 0 4px 5px rgb(0 0 0 / 30%);
74                border-radius: 8px;
75                border: 1px solid #fff;
76            }
77            dialog > div {
78                display: flex;
79                flex-direction: column;
80                height: 100%;
81            }
82            dialog header {
83                text-align: right;
84            }
85            dialog main {
86                overflow: auto;
87            }
88        `;
89        return style;
90    }
91
92    toggleDialog() {
93        if (this.#dialog.open) {
94            this.#dialog.close();
95        } else {
96            this.#dialog.show();
97        }
98    }
99}
100
101window.customElements.define('aichat-button', AIChatButton);
102