copilot-chat-widget 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -94
- package/dist/chat-widget.min.js +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +187 -219
- package/package.json +41 -40
- package/src/index.js +371 -425
- package/src/standalone.js +4 -4
package/README.md
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
# Copilot Chat Widget (NPM)
|
|
2
|
-
|
|
3
|
-
Widget chat Copilot nay co the nhung bang 2 cach:
|
|
4
|
-
|
|
5
|
-
1. Qua NPM (khuyen nghi cho SPA/Next.js/React/Vue).
|
|
6
|
-
2. Qua the `<script>` (tuong thich nguoc voi cach dang dung hien tai).
|
|
7
|
-
|
|
8
|
-
## Cai dat
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
npm install copilot-chat-widget
|
|
12
|
-
# hoac
|
|
13
|
-
yarn add copilot-chat-widget
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Su dung voi NPM
|
|
17
|
-
|
|
18
|
-
### Vanilla JS hoac framework bat ky
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
import { loadCopilotChatWidget } from "copilot-chat-widget";
|
|
22
|
-
|
|
23
|
-
loadCopilotChatWidget({
|
|
24
|
-
token: "YOUR_WIDGET_TOKEN"
|
|
25
|
-
});
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`loadCopilotChatWidget` se doi DOM san san (DOMContentLoaded) roi tu khoi dong widget. Neu ban muon tu kiem soat, co the goi thang `initCopilotChatWidget` sau khi DOM san:
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
import { initCopilotChatWidget } from "copilot-chat-widget";
|
|
32
|
-
|
|
33
|
-
await initCopilotChatWidget({
|
|
34
|
-
token: "YOUR_WIDGET_TOKEN"
|
|
35
|
-
});
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### React/Next.js
|
|
39
|
-
|
|
40
|
-
```jsx
|
|
41
|
-
import { useEffect } from "react";
|
|
42
|
-
import { loadCopilotChatWidget } from "copilot-chat-widget";
|
|
43
|
-
|
|
44
|
-
export default function Page() {
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
loadCopilotChatWidget({
|
|
47
|
-
token: process.env.NEXT_PUBLIC_CHAT_WIDGET_TOKEN
|
|
48
|
-
});
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
return <main>Your page content</main>;
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Su dung qua the `<script>` (giu nguyen hanh vi cu)
|
|
56
|
-
|
|
57
|
-
```html
|
|
58
|
-
<script
|
|
59
|
-
src="https://cdn.example.com/chat-widget.min.js"
|
|
60
|
-
data-token="YOUR_WIDGET_TOKEN"
|
|
61
|
-
></script>
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
- `data-token`: bat buoc.
|
|
65
|
-
- `data-autoload="false"`: neu muon chen script nhung tu goi `window.CopilotChat.init()` sau.
|
|
66
|
-
|
|
67
|
-
## API cau hinh
|
|
68
|
-
|
|
69
|
-
- `token` (string, bat buoc): ma token widget.
|
|
70
|
-
- `force` (boolean): cho phep khoi dong lai widget neu da co instance truoc do.
|
|
71
|
-
|
|
72
|
-
Khi da khoi dong, co the goi:
|
|
73
|
-
|
|
74
|
-
```js
|
|
75
|
-
window.CopilotChat.open(); // mo widget
|
|
76
|
-
window.CopilotChat.close(); // dong widget
|
|
77
|
-
window.CopilotChat.init(); // khoi tao lai (neu can) voi cau hinh mac dinh
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Build va publish package
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
cd webui/widget
|
|
84
|
-
npm install
|
|
85
|
-
npm run build # tao dist/index.mjs, dist/index.cjs va dist/chat-widget.min.js
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Sau khi kiem tra output trong `webui/widget/dist`, co the publish len NPM:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npm publish --access public
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Neu muon doi ten package cho phu hop scope cong ty, sua truong `name` trong `webui/widget/package.json` truoc khi publish.
|
|
1
|
+
# Copilot Chat Widget (NPM)
|
|
2
|
+
|
|
3
|
+
Widget chat Copilot nay co the nhung bang 2 cach:
|
|
4
|
+
|
|
5
|
+
1. Qua NPM (khuyen nghi cho SPA/Next.js/React/Vue).
|
|
6
|
+
2. Qua the `<script>` (tuong thich nguoc voi cach dang dung hien tai).
|
|
7
|
+
|
|
8
|
+
## Cai dat
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install copilot-chat-widget
|
|
12
|
+
# hoac
|
|
13
|
+
yarn add copilot-chat-widget
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Su dung voi NPM
|
|
17
|
+
|
|
18
|
+
### Vanilla JS hoac framework bat ky
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { loadCopilotChatWidget } from "copilot-chat-widget";
|
|
22
|
+
|
|
23
|
+
loadCopilotChatWidget({
|
|
24
|
+
token: "YOUR_WIDGET_TOKEN"
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`loadCopilotChatWidget` se doi DOM san san (DOMContentLoaded) roi tu khoi dong widget. Neu ban muon tu kiem soat, co the goi thang `initCopilotChatWidget` sau khi DOM san:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { initCopilotChatWidget } from "copilot-chat-widget";
|
|
32
|
+
|
|
33
|
+
await initCopilotChatWidget({
|
|
34
|
+
token: "YOUR_WIDGET_TOKEN"
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### React/Next.js
|
|
39
|
+
|
|
40
|
+
```jsx
|
|
41
|
+
import { useEffect } from "react";
|
|
42
|
+
import { loadCopilotChatWidget } from "copilot-chat-widget";
|
|
43
|
+
|
|
44
|
+
export default function Page() {
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
loadCopilotChatWidget({
|
|
47
|
+
token: process.env.NEXT_PUBLIC_CHAT_WIDGET_TOKEN
|
|
48
|
+
});
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
return <main>Your page content</main>;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Su dung qua the `<script>` (giu nguyen hanh vi cu)
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<script
|
|
59
|
+
src="https://cdn.example.com/chat-widget.min.js"
|
|
60
|
+
data-token="YOUR_WIDGET_TOKEN"
|
|
61
|
+
></script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- `data-token`: bat buoc.
|
|
65
|
+
- `data-autoload="false"`: neu muon chen script nhung tu goi `window.CopilotChat.init()` sau.
|
|
66
|
+
|
|
67
|
+
## API cau hinh
|
|
68
|
+
|
|
69
|
+
- `token` (string, bat buoc): ma token widget.
|
|
70
|
+
- `force` (boolean): cho phep khoi dong lai widget neu da co instance truoc do.
|
|
71
|
+
|
|
72
|
+
Khi da khoi dong, co the goi:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
window.CopilotChat.open(); // mo widget
|
|
76
|
+
window.CopilotChat.close(); // dong widget
|
|
77
|
+
window.CopilotChat.init(); // khoi tao lai (neu can) voi cau hinh mac dinh
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Build va publish package
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd webui/widget
|
|
84
|
+
npm install
|
|
85
|
+
npm run build # tao dist/index.mjs, dist/index.cjs va dist/chat-widget.min.js
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Sau khi kiem tra output trong `webui/widget/dist`, co the publish len NPM:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm publish --access public
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Neu muon doi ten package cho phu hop scope cong ty, sua truong `name` trong `webui/widget/package.json` truoc khi publish.
|
package/dist/chat-widget.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(){"use strict";(function(){if(typeof window>"u"||window.__copilotWidgetLoaded)return;window.__copilotWidgetLoaded=!0;const b=64,C=720,E=document.currentScript,v="http://localhost:3000",k=e=>{if(!e?.src)return{};try{const n=new URL(e.src,window.location.href),r={};return n.searchParams.forEach((a,h)=>{r[h]=a}),r}catch(n){return console.warn("[CopilotChat] Failed to parse script query params:",n),{}}},I=e=>{document.readyState==="complete"||document.readyState==="interactive"?setTimeout(e,0):document.addEventListener("DOMContentLoaded",e)},S=e=>e.endsWith("/")?e.slice(0,-1):e,A=({iframeUrl:e,launcherIcon:n,theme:r={}})=>{const a=document.querySelector("[data-copilot-widget-root]");a&&a.remove();const{accent:h="linear-gradient(135deg, #0078ff, #00c6ff)"}=r,m=document.createElement("div");m.setAttribute("data-copilot-widget-root","true");const u=m.attachShadow({mode:"open"});document.body.appendChild(m);const t=document.createElement("button");t.type="button",t.setAttribute("aria-label","Open Copilot chat"),t.innerHTML=`
|
|
2
2
|
<img
|
|
3
3
|
src="${n}"
|
|
4
4
|
alt="Copilot chat launcher"
|
|
5
5
|
style="width: 38px; height: 38px; object-fit: contain; border-radius: 50%; pointer-events: none;"
|
|
6
6
|
/>
|
|
7
|
-
`,Object.assign(
|
|
7
|
+
`,Object.assign(t.style,{position:"fixed",bottom:"24px",right:"24px",width:`${b}px`,height:`${b}px`,borderRadius:"50%",border:"none",background:h,color:"white",cursor:"pointer",zIndex:999998,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 6px 14px rgba(0,0,0,0.25)",transition:"all 0.25s ease"}),t.onmouseover=()=>{t.style.transform="scale(1.12)",t.style.boxShadow="0 10px 25px rgba(0,0,0,0.3)"},t.onmouseout=()=>{t.style.transform="scale(1)",t.style.boxShadow="0 6px 14px rgba(0,0,0,0.25)"};const o=document.createElement("div");o.setAttribute("data-copilot-widget-root","true"),Object.assign(o.style,{display:"none",position:"fixed",bottom:`${b+36}px`,right:"24px",zIndex:"999999",transformOrigin:"bottom right",transform:"scale(0.8) translateY(20px)",opacity:"0",transition:"all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)"});const i=document.createElement("div"),c=document.createElement("div"),g=document.createElement("div");Object.assign(i.style,{position:"absolute",bottom:"-14px",right:"28px",width:"30px",height:"20px",pointerEvents:"none",display:"none",zIndex:"1"}),Object.assign(c.style,{position:"absolute",bottom:"0",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"15px solid transparent",borderRight:"15px solid transparent",borderTop:"15px solid rgba(15,23,42,0.1)"}),Object.assign(g.style,{position:"absolute",bottom:"2px",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"13px solid transparent",borderRight:"13px solid transparent",borderTop:"13px solid white",boxShadow:"0 6px 16px rgba(15,23,42,0.12)",borderRadius:"2px"}),i.appendChild(c),i.appendChild(g);const s=document.createElement("div");Object.assign(s.style,{width:`${C}px`,maxWidth:"calc(100vw - 48px)",height:`${Math.min(C,Math.max(320,window.innerHeight-140))}px`,maxHeight:"calc(100vh - 150px)",borderRadius:"20px",background:"white",border:"1px solid rgba(15,23,42,0.12)",boxShadow:"0 18px 45px rgba(15,23,42,0.16)",overflow:"hidden"}),u.appendChild(s);const d=document.createElement("iframe");d.src=e,d.title="Copilot chat widget",d.allow="clipboard-read; clipboard-write; microphone; camera; display-capture",d.setAttribute("scrolling","no"),Object.assign(d.style,{width:"100%",height:"100%",border:"none",display:"block",background:"transparent",overflow:"hidden"}),u.appendChild(s),s.appendChild(d),o.appendChild(i),o.appendChild(s),document.body.appendChild(t),document.body.appendChild(o),window.addEventListener("message",p=>{p.data?.type==="WIDGET_READY"&&d.contentWindow.postMessage({type:"INIT_WIDGET"},"*")});let l=!1;const w=()=>{l&&(l=!1,o.style.opacity="0",o.style.transform="scale(0.8) translateY(20px)",i.style.display="none",setTimeout(()=>{o.style.display="none"},250),t.style.transform="scale(1)")};t.onclick=p=>{p.stopPropagation(),l=!l,l?(o.style.display="block",i.style.display="block",requestAnimationFrame(()=>{o.style.opacity="1",o.style.transform="scale(1) translateY(0)"})):w()},window.addEventListener("message",p=>{p?.data?.type==="CHAT_CLOSED"&&w()}),document.addEventListener("click",p=>{const x=p.target;x&&l&&!o.contains(x)&&x!==t&&w()});const y={close:w,open:()=>{l||t.click()}};return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.close=y.close,window.CopilotChat.open=y.open,y},f=e=>{console.error(`[CopilotChat] ${e}`)},U=()=>E||Array.from(document.querySelectorAll("script")).reverse().find(r=>r.dataset?.token||r.src.includes("chat-widget"))||null;I(async()=>{const e=U();if(!e){f("Unable to locate the embedding script tag on the page.");return}const n=window.CopilotChatConfig||{},r=e.dataset||{},a=k(e),h=n.token||r.token||a.token;if(!h){f("Missing token (provide via window.CopilotChatConfig.token or data-token attribute).");return}const m=S(v),u=n.theme&&n.theme.accent||n.accent||r.themeAccent||a.themeAccent;try{const t=await fetch(`${m}/api/chat-widget/config?token=${encodeURIComponent(h)}`,{credentials:"omit",mode:"cors"});if(!t.ok)throw new Error(`Server responded with ${t.status}`);const o=await t.json();if(!o?.iframeUrl||!o?.launcherIcon)throw new Error("Received incomplete widget configuration from server.");const i={iframeUrl:o.iframeUrl,launcherIcon:o.launcherIcon,theme:{accent:u||o.theme?.accent||void 0}};window.CopilotChat=window.CopilotChat||{},window.CopilotChat.init=(c={})=>{const g={accent:c.theme?.accent||c.accent||i.theme.accent||(typeof n.theme=="object"?n.theme.accent:void 0)||n.accent},s={iframeUrl:c.iframeUrl||i.iframeUrl,launcherIcon:c.launcherIcon||i.launcherIcon,theme:g};return A(s)},window.CopilotChat.init(n)}catch(t){f(t instanceof Error?t.message:"Unknown error during widget bootstrap.")}})})()})();
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";(function(){if(typeof window>"u"||window.__copilotWidgetLoaded)return;window.__copilotWidgetLoaded=!0;const b=64,C=720,E=document.currentScript,v="http://localhost:3000",k=e=>{if(!e?.src)return{};try{const n=new URL(e.src,window.location.href),r={};return n.searchParams.forEach((a,h)=>{r[h]=a}),r}catch(n){return console.warn("[CopilotChat] Failed to parse script query params:",n),{}}},I=e=>{document.readyState==="complete"||document.readyState==="interactive"?setTimeout(e,0):document.addEventListener("DOMContentLoaded",e)},S=e=>e.endsWith("/")?e.slice(0,-1):e,A=({iframeUrl:e,launcherIcon:n,theme:r={}})=>{const a=document.querySelector("[data-copilot-widget-root]");a&&a.remove();const{accent:h="linear-gradient(135deg, #0078ff, #00c6ff)"}=r,m=document.createElement("div");m.setAttribute("data-copilot-widget-root","true");const u=m.attachShadow({mode:"open"});document.body.appendChild(m);const t=document.createElement("button");t.type="button",t.setAttribute("aria-label","Open Copilot chat"),t.innerHTML=`
|
|
2
2
|
<img
|
|
3
3
|
src="${n}"
|
|
4
4
|
alt="Copilot chat launcher"
|
|
5
5
|
style="width: 38px; height: 38px; object-fit: contain; border-radius: 50%; pointer-events: none;"
|
|
6
6
|
/>
|
|
7
|
-
`,Object.assign(
|
|
7
|
+
`,Object.assign(t.style,{position:"fixed",bottom:"24px",right:"24px",width:`${b}px`,height:`${b}px`,borderRadius:"50%",border:"none",background:h,color:"white",cursor:"pointer",zIndex:999998,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 6px 14px rgba(0,0,0,0.25)",transition:"all 0.25s ease"}),t.onmouseover=()=>{t.style.transform="scale(1.12)",t.style.boxShadow="0 10px 25px rgba(0,0,0,0.3)"},t.onmouseout=()=>{t.style.transform="scale(1)",t.style.boxShadow="0 6px 14px rgba(0,0,0,0.25)"};const o=document.createElement("div");o.setAttribute("data-copilot-widget-root","true"),Object.assign(o.style,{display:"none",position:"fixed",bottom:`${b+36}px`,right:"24px",zIndex:"999999",transformOrigin:"bottom right",transform:"scale(0.8) translateY(20px)",opacity:"0",transition:"all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)"});const i=document.createElement("div"),c=document.createElement("div"),g=document.createElement("div");Object.assign(i.style,{position:"absolute",bottom:"-14px",right:"28px",width:"30px",height:"20px",pointerEvents:"none",display:"none",zIndex:"1"}),Object.assign(c.style,{position:"absolute",bottom:"0",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"15px solid transparent",borderRight:"15px solid transparent",borderTop:"15px solid rgba(15,23,42,0.1)"}),Object.assign(g.style,{position:"absolute",bottom:"2px",left:"0",right:"0",margin:"0 auto",width:"0",height:"0",borderLeft:"13px solid transparent",borderRight:"13px solid transparent",borderTop:"13px solid white",boxShadow:"0 6px 16px rgba(15,23,42,0.12)",borderRadius:"2px"}),i.appendChild(c),i.appendChild(g);const s=document.createElement("div");Object.assign(s.style,{width:`${C}px`,maxWidth:"calc(100vw - 48px)",height:`${Math.min(C,Math.max(320,window.innerHeight-140))}px`,maxHeight:"calc(100vh - 150px)",borderRadius:"20px",background:"white",border:"1px solid rgba(15,23,42,0.12)",boxShadow:"0 18px 45px rgba(15,23,42,0.16)",overflow:"hidden"}),u.appendChild(s);const d=document.createElement("iframe");d.src=e,d.title="Copilot chat widget",d.allow="clipboard-read; clipboard-write; microphone; camera; display-capture",d.setAttribute("scrolling","no"),Object.assign(d.style,{width:"100%",height:"100%",border:"none",display:"block",background:"transparent",overflow:"hidden"}),u.appendChild(s),s.appendChild(d),o.appendChild(i),o.appendChild(s),document.body.appendChild(t),document.body.appendChild(o),window.addEventListener("message",p=>{p.data?.type==="WIDGET_READY"&&d.contentWindow.postMessage({type:"INIT_WIDGET"},"*")});let l=!1;const w=()=>{l&&(l=!1,o.style.opacity="0",o.style.transform="scale(0.8) translateY(20px)",i.style.display="none",setTimeout(()=>{o.style.display="none"},250),t.style.transform="scale(1)")};t.onclick=p=>{p.stopPropagation(),l=!l,l?(o.style.display="block",i.style.display="block",requestAnimationFrame(()=>{o.style.opacity="1",o.style.transform="scale(1) translateY(0)"})):w()},window.addEventListener("message",p=>{p?.data?.type==="CHAT_CLOSED"&&w()}),document.addEventListener("click",p=>{const x=p.target;x&&l&&!o.contains(x)&&x!==t&&w()});const y={close:w,open:()=>{l||t.click()}};return window.CopilotChat=window.CopilotChat||{},window.CopilotChat.close=y.close,window.CopilotChat.open=y.open,y},f=e=>{console.error(`[CopilotChat] ${e}`)},U=()=>E||Array.from(document.querySelectorAll("script")).reverse().find(r=>r.dataset?.token||r.src.includes("chat-widget"))||null;I(async()=>{const e=U();if(!e){f("Unable to locate the embedding script tag on the page.");return}const n=window.CopilotChatConfig||{},r=e.dataset||{},a=k(e),h=n.token||r.token||a.token;if(!h){f("Missing token (provide via window.CopilotChatConfig.token or data-token attribute).");return}const m=S(v),u=n.theme&&n.theme.accent||n.accent||r.themeAccent||a.themeAccent;try{const t=await fetch(`${m}/api/chat-widget/config?token=${encodeURIComponent(h)}`,{credentials:"omit",mode:"cors"});if(!t.ok)throw new Error(`Server responded with ${t.status}`);const o=await t.json();if(!o?.iframeUrl||!o?.launcherIcon)throw new Error("Received incomplete widget configuration from server.");const i={iframeUrl:o.iframeUrl,launcherIcon:o.launcherIcon,theme:{accent:u||o.theme?.accent||void 0}};window.CopilotChat=window.CopilotChat||{},window.CopilotChat.init=(c={})=>{const g={accent:c.theme?.accent||c.accent||i.theme.accent||(typeof n.theme=="object"?n.theme.accent:void 0)||n.accent},s={iframeUrl:c.iframeUrl||i.iframeUrl,launcherIcon:c.launcherIcon||i.launcherIcon,theme:g};return A(s)},window.CopilotChat.init(n)}catch(t){f(t instanceof Error?t.message:"Unknown error during widget bootstrap.")}})})();
|