@@ -4,57 +4,91 @@ import createShadowRoot from "./createShadowRoot";
44import cssText from "../src/index.css?inline" ;
55import { ShadowRootProvider } from "@/providers/ShadowRootProvider" ;
66
7- type DocsChatbotConfig = {
8- containerId : string ;
9- } & DocsChatbotProps ;
7+ class DocsChatbotElement extends HTMLElement {
8+ private root : ReturnType < typeof createShadowRoot > [ "root" ] | null = null ;
9+ private portalContainer : HTMLDivElement | null = null ;
1010
11- class DocsChatbotWidget {
12- init ( config : DocsChatbotConfig ) : void {
13- const { containerId, ...chatbotProps } = config ;
14-
15- const container = document . getElementById ( containerId ) ;
16- if ( ! container ) {
17- console . error (
18- `SqliteAi Chatbot: Container with id "${ containerId } " not found`
19- ) ;
20- return ;
21- }
11+ static get observedAttributes ( ) {
12+ return [
13+ "search-url" ,
14+ "api-key" ,
15+ "title" ,
16+ "empty-state-title" ,
17+ "empty-state-description" ,
18+ ] ;
19+ }
2220
21+ connectedCallback ( ) {
2322 try {
24- const { root, shadow } = createShadowRoot ( container , cssText ) ;
23+ const { root, shadow } = createShadowRoot ( this , cssText ) ;
24+ this . root = root ;
2525
26- // Create portal container for dialogs inside shadow root
2726 const portalContainer = document . createElement ( "div" ) ;
2827 portalContainer . id = "portal-container" ;
28+ this . portalContainer = portalContainer ;
2929 shadow . appendChild ( portalContainer ) ;
3030
31- root . render (
32- React . createElement (
33- ShadowRootProvider ,
34- { value : portalContainer } ,
35- React . createElement ( DocsChatbot , chatbotProps )
36- )
37- ) ;
31+ this . render ( ) ;
3832 } catch ( error ) {
3933 console . error ( "SqliteAi Chatbot: Failed to initialize" , error ) ;
4034 }
4135 }
42- }
4336
44- const chatbotWidget = new DocsChatbotWidget ( ) ;
37+ attributeChangedCallback ( ) {
38+ if ( this . root ) {
39+ this . render ( ) ;
40+ }
41+ }
42+
43+ private render ( ) {
44+ if ( ! this . root || ! this . portalContainer ) return ;
4545
46- declare global {
47- interface Window {
48- DocsChatbot : DocsChatbotWidget ;
46+ const searchUrl = this . getAttribute ( "search-url" ) ;
47+ const apiKey = this . getAttribute ( "api-key" ) ;
48+ const title = this . getAttribute ( "title" ) ;
49+ const emptyStateTitle = this . getAttribute ( "empty-state-title" ) ;
50+ const emptyStateDescription = this . getAttribute ( "empty-state-description" ) ;
51+
52+ if ( ! searchUrl || ! apiKey || ! title ) {
53+ console . error (
54+ "SqliteAi Chatbot: Missing required attributes (search-url, api-key, title)"
55+ ) ;
56+ return ;
57+ }
58+
59+ const chatbotProps : DocsChatbotProps = {
60+ searchUrl,
61+ apiKey,
62+ title,
63+ ...( emptyStateTitle &&
64+ emptyStateDescription && {
65+ emptyState : {
66+ title : emptyStateTitle ,
67+ description : emptyStateDescription ,
68+ } ,
69+ } ) ,
70+ } ;
71+
72+ this . root . render (
73+ React . createElement (
74+ ShadowRootProvider ,
75+ { value : this . portalContainer } ,
76+ React . createElement ( DocsChatbot , chatbotProps )
77+ )
78+ ) ;
4979 }
50- var DocsChatbot : DocsChatbotWidget | undefined ;
51- }
5280
53- if ( typeof window !== "undefined" ) {
54- window . DocsChatbot = chatbotWidget ;
81+ disconnectedCallback ( ) {
82+ if ( this . root ) {
83+ this . root . unmount ( ) ;
84+ this . root = null ;
85+ this . portalContainer = null ;
86+ }
87+ }
5588}
56- if ( typeof globalThis !== "undefined" ) {
57- globalThis . DocsChatbot = chatbotWidget ;
89+
90+ if ( typeof window !== "undefined" && ! customElements . get ( "docs-chatbot" ) ) {
91+ customElements . define ( "docs-chatbot" , DocsChatbotElement ) ;
5892}
5993
60- export default chatbotWidget ;
94+ export default DocsChatbotElement ;
0 commit comments