@enjoys/react-chatbot-plugin 1.0.0

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 ADDED
@@ -0,0 +1,15 @@
1
+ # chatbot
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.3.6. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
package/dist/index.cjs ADDED
@@ -0,0 +1,9 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var G=Object.create,w=Object.defineProperty,$=Object.getOwnPropertyDescriptor,H=Object.getOwnPropertyNames,Q=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty,K=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(var l=H(t),o=0,c=l.length,s;o<c;o++)s=l[o],!Y.call(e,s)&&s!==r&&w(e,s,{get:(g=>t[g]).bind(null,s),enumerable:!(a=$(t,s))||a.enumerable});return e},U=(e,t,r)=>(r=e!=null?G(Q(e)):{},K(t||!e||!e.__esModule?w(r,"default",{value:e,enumerable:!0}):r,e));let x=require("react");x=U(x);let n=require("react/jsx-runtime");function V(e,t){switch(t.type){case"TOGGLE_OPEN":return{...e,isOpen:!e.isOpen};case"SET_OPEN":return{...e,isOpen:t.payload};case"ADD_MESSAGE":return{...e,messages:[...e.messages,t.payload]};case"ADD_MESSAGES":return{...e,messages:[...e.messages,...t.payload]};case"SET_TYPING":return{...e,isTyping:t.payload};case"DISMISS_WELCOME":return{...e,showWelcome:!1};case"SET_STEP":return{...e,currentStepId:t.payload};case"SET_DATA":return{...e,collectedData:{...e.collectedData,...t.payload}};case"SET_LOGGED_IN":return{...e,isLoggedIn:t.payload};case"CLEAR_QUICK_REPLIES":return{...e,messages:e.messages.map(r=>r.quickReplies?{...r,quickReplies:void 0}:r)};default:return e}}var J=e=>({isOpen:e.defaultOpen??!1,messages:e.initialMessages??[],isTyping:!1,showWelcome:!!e.welcomeScreen,currentStepId:null,collectedData:{},isLoggedIn:!e.loginForm}),y=(0,x.createContext)(null);function S(){const e=(0,x.useContext)(y);if(!e)throw new Error("useChatContext must be used within ChatProvider");return e}var X={primaryColor:"#0066FF",headerBg:"#0066FF",headerText:"#FFFFFF",bubbleBg:"#F1F1F1",bubbleText:"#333333",userBubbleBg:"#0066FF",userBubbleText:"#FFFFFF",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontSize:"14px",borderRadius:"12px",windowWidth:"380px",windowHeight:"550px"};function k(e){return{...X,...e}}function Z(e,t){return{root:{fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:"1.5"},launcher:{position:"fixed",width:"60px",height:"60px",borderRadius:"50%",backgroundColor:e.primaryColor,color:"#fff",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",transition:"transform 0.2s ease",zIndex:9998,...t?.launcher},window:{position:"fixed",width:e.windowWidth,height:e.windowHeight,maxHeight:"80vh",borderRadius:e.borderRadius,overflow:"hidden",display:"flex",flexDirection:"column",boxShadow:"0 8px 32px rgba(0,0,0,0.15)",backgroundColor:"#FFFFFF",zIndex:9999,...t?.window},header:{backgroundColor:e.headerBg,color:e.headerText,padding:"16px 20px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"12px",flexShrink:0,...t?.header},messageList:{flex:1,overflowY:"auto",padding:"16px",display:"flex",flexDirection:"column",gap:"8px",...t?.messageList},inputArea:{padding:"12px 16px",borderTop:"1px solid #E8E8E8",display:"flex",gap:"8px",alignItems:"flex-end",flexShrink:0,...t?.inputArea},botBubble:{backgroundColor:e.bubbleBg,color:e.bubbleText,padding:"10px 14px",borderRadius:"16px 16px 16px 4px",maxWidth:"80%",alignSelf:"flex-start",wordBreak:"break-word",whiteSpace:"pre-wrap"},userBubble:{backgroundColor:e.userBubbleBg,color:e.userBubbleText,padding:"10px 14px",borderRadius:"16px 16px 4px 16px",maxWidth:"80%",alignSelf:"flex-end",wordBreak:"break-word",whiteSpace:"pre-wrap"}}}var C=({onClick:e,isOpen:t,position:r,styles:a,icon:l,closeIcon:o,zIndex:c})=>{const s=r==="bottom-left"?{bottom:"20px",left:"20px"}:{bottom:"20px",right:"20px"};return(0,n.jsx)("button",{onClick:e,"aria-label":t?"Close chat":"Open chat",style:{...a.launcher,...s,...c!=null?{zIndex:c}:{},transform:t?"scale(0.9)":"scale(1)"},children:t?o??(0,n.jsx)(te,{}):l??(0,n.jsx)(ee,{})})},ee=()=>(0,n.jsx)("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,n.jsx)("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})}),te=()=>(0,n.jsxs)("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),(0,n.jsx)("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),F=({config:e,styles:t,onClose:r})=>(0,n.jsxs)("div",{style:t.header,children:[(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"10px",flex:1},children:[e.avatar&&(0,n.jsx)("img",{src:e.avatar,alt:"",style:{width:"36px",height:"36px",borderRadius:"50%",objectFit:"cover"}}),(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{style:{fontWeight:600,fontSize:"15px"},children:e.title??"Chat with us"}),e.subtitle&&(0,n.jsx)("div",{style:{fontSize:"12px",opacity:.85},children:e.subtitle})]})]}),e.showClose!==!1&&(0,n.jsx)("button",{onClick:r,"aria-label":"Close chat",style:{background:"none",border:"none",color:"inherit",cursor:"pointer",padding:"4px",display:"flex",alignItems:"center"},children:(0,n.jsxs)("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),(0,n.jsx)("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),D=({content:e,onDismiss:t,primaryColor:r})=>(0,n.jsxs)("div",{style:{flex:1,display:"flex",flexDirection:"column",overflow:"auto"},children:[(0,n.jsx)("div",{style:{flex:1,padding:"20px",overflow:"auto"},children:e}),(0,n.jsx)("div",{style:{padding:"12px 16px",borderTop:"1px solid #E8E8E8",flexShrink:0},children:(0,n.jsx)("button",{onClick:t,style:{width:"100%",padding:"12px",backgroundColor:r,color:"#fff",border:"none",borderRadius:"8px",fontSize:"14px",fontWeight:600,cursor:"pointer"},children:"Start Chat"})})]}),T=({field:e,value:t,onChange:r,error:a})=>{const l=e.type==="textarea",o=e.type==="textarea"?void 0:e.type,c={width:"100%",padding:"8px 12px",border:`1px solid ${a?"#E53E3E":"#D1D5DB"}`,borderRadius:"8px",fontSize:"13px",fontFamily:"inherit",outline:"none",boxSizing:"border-box",transition:"border-color 0.15s ease"};return(0,n.jsxs)("div",{style:{marginBottom:"12px"},children:[e.label&&(0,n.jsxs)("label",{style:{display:"block",marginBottom:"4px",fontSize:"13px",fontWeight:500},children:[e.label,e.required&&(0,n.jsx)("span",{style:{color:"#E53E3E",marginLeft:"2px"},children:"*"})]}),l?(0,n.jsx)("textarea",{value:t,onChange:s=>r(s.target.value),placeholder:e.placeholder,required:e.required,rows:3,style:{...c,resize:"vertical"},minLength:e.validation?.minLength,maxLength:e.validation?.maxLength}):(0,n.jsx)("input",{type:o,value:t,onChange:s=>r(s.target.value),placeholder:e.placeholder,required:e.required,style:c,min:e.validation?.min,max:e.validation?.max,minLength:e.validation?.minLength,maxLength:e.validation?.maxLength,pattern:e.validation?.pattern}),a&&(0,n.jsx)("div",{style:{color:"#E53E3E",fontSize:"12px",marginTop:"2px"},children:a})]})},I=({field:e,value:t,onChange:r,error:a})=>{const l=e.type==="multiselect"||e.multiple,o=s=>{r(l?Array.from(s.target.selectedOptions,g=>g.value):s.target.value)},c=l?Array.isArray(t)?t:[t].filter(Boolean):typeof t=="string"?t:"";return(0,n.jsxs)("div",{style:{marginBottom:"12px"},children:[e.label&&(0,n.jsxs)("label",{style:{display:"block",marginBottom:"4px",fontSize:"13px",fontWeight:500},children:[e.label,e.required&&(0,n.jsx)("span",{style:{color:"#E53E3E",marginLeft:"2px"},children:"*"})]}),(0,n.jsxs)("select",{value:c,onChange:o,multiple:l,required:e.required,style:{width:"100%",padding:"8px 12px",border:`1px solid ${a?"#E53E3E":"#D1D5DB"}`,borderRadius:"8px",fontSize:"13px",fontFamily:"inherit",outline:"none",backgroundColor:"#fff",boxSizing:"border-box",...l?{minHeight:"80px"}:{}},children:[!l&&(0,n.jsx)("option",{value:"",children:"Select..."}),e.options?.map(s=>(0,n.jsx)("option",{value:s.value,children:s.label},s.value))]}),l&&(0,n.jsx)("div",{style:{fontSize:"11px",color:"#888",marginTop:"2px"},children:"Hold Ctrl/Cmd to select multiple"}),a&&(0,n.jsx)("div",{style:{color:"#E53E3E",fontSize:"12px",marginTop:"2px"},children:a})]})},R=({field:e,value:t,onChange:r,error:a})=>(0,n.jsxs)("div",{style:{marginBottom:"12px"},children:[e.label&&(0,n.jsxs)("label",{style:{display:"block",marginBottom:"6px",fontSize:"13px",fontWeight:500},children:[e.label,e.required&&(0,n.jsx)("span",{style:{color:"#E53E3E",marginLeft:"2px"},children:"*"})]}),(0,n.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:"6px"},children:e.options?.map(l=>(0,n.jsxs)("label",{style:{display:"flex",alignItems:"center",gap:"8px",cursor:"pointer",fontSize:"13px"},children:[(0,n.jsx)("input",{type:"radio",name:e.name,value:l.value,checked:t===l.value,onChange:()=>r(l.value),style:{margin:0}}),l.label]},l.value))}),a&&(0,n.jsx)("div",{style:{color:"#E53E3E",fontSize:"12px",marginTop:"2px"},children:a})]}),_=({field:e,value:t,onChange:r,error:a})=>{const l=o=>{t.includes(o)?r(t.filter(c=>c!==o)):r([...t,o])};return(0,n.jsxs)("div",{style:{marginBottom:"12px"},children:[e.label&&(0,n.jsxs)("label",{style:{display:"block",marginBottom:"6px",fontSize:"13px",fontWeight:500},children:[e.label,e.required&&(0,n.jsx)("span",{style:{color:"#E53E3E",marginLeft:"2px"},children:"*"})]}),(0,n.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:"6px"},children:e.options?.map(o=>(0,n.jsxs)("label",{style:{display:"flex",alignItems:"center",gap:"8px",cursor:"pointer",fontSize:"13px"},children:[(0,n.jsx)("input",{type:"checkbox",checked:t.includes(o.value),onChange:()=>l(o.value),style:{margin:0}}),o.label]},o.value))}),a&&(0,n.jsx)("div",{style:{color:"#E53E3E",fontSize:"12px",marginTop:"2px"},children:a})]})},L=({field:e,value:t,onChange:r,error:a,primaryColor:l})=>{const o=(0,x.useRef)(null),c=t?Array.from(t).map(s=>s.name).join(", "):"";return(0,n.jsxs)("div",{style:{marginBottom:"12px"},children:[e.label&&(0,n.jsxs)("label",{style:{display:"block",marginBottom:"4px",fontSize:"13px",fontWeight:500},children:[e.label,e.required&&(0,n.jsx)("span",{style:{color:"#E53E3E",marginLeft:"2px"},children:"*"})]}),(0,n.jsx)("input",{ref:o,type:"file",accept:e.accept,multiple:e.multiple,onChange:s=>r(s.target.files),style:{display:"none"}}),(0,n.jsx)("button",{type:"button",onClick:()=>o.current?.click(),style:{padding:"8px 16px",border:`1px dashed ${a?"#E53E3E":"#D1D5DB"}`,borderRadius:"8px",backgroundColor:"#FAFAFA",cursor:"pointer",fontSize:"13px",color:"#555",width:"100%",textAlign:"left"},children:c||e.placeholder||"Choose file(s)..."}),c&&(0,n.jsxs)("div",{style:{fontSize:"12px",color:l,marginTop:"4px"},children:[Array.from(t).length," file(s) selected"]}),a&&(0,n.jsx)("div",{style:{color:"#E53E3E",fontSize:"12px",marginTop:"2px"},children:a})]})},v=({config:e,onSubmit:t,primaryColor:r})=>{const[a,l]=(0,x.useState)(()=>{const i={};for(const d of e.fields)d.defaultValue!==void 0?i[d.name]=d.defaultValue:d.type==="checkbox"||d.type==="multiselect"?i[d.name]=[]:d.type==="file"?i[d.name]=null:i[d.name]="";return i}),[o,c]=(0,x.useState)({}),[s,g]=(0,x.useState)(!1),u=(0,x.useCallback)((i,d)=>{l(b=>({...b,[i]:d})),c(b=>{const j={...b};return delete j[i],j})},[]),p=()=>{const i={};for(const d of e.fields){const b=a[d.name];if(d.required&&(b===""||b===null||b===void 0||Array.isArray(b)&&b.length===0)){i[d.name]=d.validation?.message??`${d.label||d.name} is required`;continue}d.validation?.pattern&&typeof b=="string"&&b&&(new RegExp(d.validation.pattern).test(b)||(i[d.name]=d.validation.message??"Invalid format"))}return c(i),Object.keys(i).length===0},h=i=>{i.preventDefault(),p()&&(g(!0),t(a))};return s?(0,n.jsx)("div",{style:{padding:"12px",backgroundColor:"#F0FFF4",borderRadius:"8px",fontSize:"13px",color:"#276749",textAlign:"center"},children:"Submitted successfully"}):(0,n.jsxs)("form",{onSubmit:h,style:{backgroundColor:"#FAFAFA",borderRadius:"10px",padding:"16px",border:"1px solid #E8E8E8"},children:[e.title&&(0,n.jsx)("div",{style:{fontWeight:600,fontSize:"14px",marginBottom:"4px"},children:e.title}),e.description&&(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888",marginBottom:"12px"},children:e.description}),e.fields.map(i=>(0,n.jsx)(ne,{field:i,value:a[i.name],onChange:d=>u(i.name,d),error:o[i.name],primaryColor:r},i.name)),(0,n.jsx)("button",{type:"submit",style:{width:"100%",padding:"10px",backgroundColor:r,color:"#fff",border:"none",borderRadius:"8px",fontSize:"14px",fontWeight:600,cursor:"pointer",marginTop:"4px"},children:e.submitLabel??"Submit"})]})},ne=({field:e,value:t,onChange:r,error:a,primaryColor:l})=>{switch(e.type){case"text":case"email":case"password":case"number":case"tel":case"url":case"textarea":case"date":case"time":return(0,n.jsx)(T,{field:e,value:String(t??""),onChange:r,error:a});case"select":case"multiselect":return(0,n.jsx)(I,{field:e,value:t,onChange:r,error:a});case"radio":return(0,n.jsx)(R,{field:e,value:String(t??""),onChange:r,error:a});case"checkbox":return(0,n.jsx)(_,{field:e,value:t??[],onChange:r,error:a});case"file":return(0,n.jsx)(L,{field:e,value:t,onChange:r,error:a,primaryColor:l});case"hidden":return(0,n.jsx)("input",{type:"hidden",name:e.name,value:String(t??"")});default:return null}},O=({config:e,onLogin:t,primaryColor:r})=>(0,n.jsx)("div",{style:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",padding:"20px",overflow:"auto"},children:(0,n.jsx)(v,{config:e,onSubmit:t,primaryColor:r})}),B=({message:e,styles:t})=>{const r=e.sender==="bot"?t.botBubble:t.userBubble;return!e.text&&!e.attachment?null:(0,n.jsxs)("div",{style:r,children:[e.text&&(0,n.jsx)("span",{children:e.text}),e.attachment&&(0,n.jsx)("div",{style:{marginTop:e.text?"6px":0},children:(0,n.jsxs)("a",{href:e.attachment.url,target:"_blank",rel:"noopener noreferrer",style:{color:"inherit",textDecoration:"underline",fontSize:"13px"},children:["📎 ",e.attachment.name]})})]})},z=({replies:e,onSelect:t,primaryColor:r})=>(0,n.jsx)("div",{style:{display:"flex",flexWrap:"wrap",gap:"6px",alignSelf:"flex-start",maxWidth:"90%"},children:e.map(a=>(0,n.jsx)("button",{onClick:()=>t(a.value,a.label),style:{padding:"6px 14px",borderRadius:"18px",border:`1px solid ${r}`,backgroundColor:"transparent",color:r,cursor:"pointer",fontSize:"13px",fontWeight:500,transition:"all 0.15s ease"},onMouseEnter:l=>{l.currentTarget.style.backgroundColor=r,l.currentTarget.style.color="#fff"},onMouseLeave:l=>{l.currentTarget.style.backgroundColor="transparent",l.currentTarget.style.color=r},children:a.label},a.value))}),A=({color:e})=>{const t={width:"8px",height:"8px",borderRadius:"50%",backgroundColor:e,opacity:.4,animation:"chatbot-typing-bounce 1.4s infinite ease-in-out"};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("style",{children:`
2
+ @keyframes chatbot-typing-bounce {
3
+ 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
4
+ 40% { transform: scale(1); opacity: 1; }
5
+ }
6
+ `}),(0,n.jsxs)("div",{style:{display:"flex",gap:"4px",padding:"12px 16px",backgroundColor:"#F1F1F1",borderRadius:"16px 16px 16px 4px",alignSelf:"flex-start",alignItems:"center"},children:[(0,n.jsx)("span",{style:{...t,animationDelay:"0s"}}),(0,n.jsx)("span",{style:{...t,animationDelay:"0.2s"}}),(0,n.jsx)("span",{style:{...t,animationDelay:"0.4s"}})]})]})},M=({messages:e,isTyping:t,styles:r,primaryColor:a,onQuickReply:l,onFormSubmit:o})=>{const c=(0,x.useRef)(null);return(0,x.useEffect)(()=>{c.current?.scrollIntoView({behavior:"smooth"})},[e,t]),(0,n.jsxs)("div",{style:r.messageList,children:[e.map(s=>(0,n.jsxs)(x.default.Fragment,{children:[(0,n.jsx)(B,{message:s,styles:r}),s.quickReplies&&s.quickReplies.length>0&&(0,n.jsx)(z,{replies:s.quickReplies,onSelect:l,primaryColor:a}),s.form&&(0,n.jsx)("div",{style:{alignSelf:"flex-start",width:"90%"},children:(0,n.jsx)(v,{config:s.form,onSubmit:g=>o(s.form.id,g),primaryColor:a})})]},s.id)),t&&(0,n.jsx)(A,{color:a}),(0,n.jsx)("div",{ref:c})]})},P=({onSend:e,placeholder:t="Type a message...",primaryColor:r,disabled:a,styleOverride:l})=>{const[o,c]=(0,x.useState)(""),s=(0,x.useRef)(null),g=()=>{const p=o.trim();p&&(e(p),c(""),s.current?.focus())},u=p=>{p.key==="Enter"&&!p.shiftKey&&(p.preventDefault(),g())};return(0,n.jsxs)("div",{style:{display:"flex",gap:"8px",alignItems:"flex-end",...l},children:[(0,n.jsx)("textarea",{ref:s,value:o,onChange:p=>c(p.target.value),onKeyDown:u,placeholder:t,disabled:a,rows:1,style:{flex:1,padding:"10px 14px",border:"1px solid #E0E0E0",borderRadius:"20px",outline:"none",resize:"none",fontFamily:"inherit",fontSize:"14px",lineHeight:"1.4",maxHeight:"100px",overflowY:"auto"}}),(0,n.jsx)("button",{onClick:g,disabled:a||!o.trim(),"aria-label":"Send message",style:{width:"38px",height:"38px",borderRadius:"50%",backgroundColor:o.trim()?r:"#CCC",color:"#fff",border:"none",cursor:o.trim()?"pointer":"default",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,transition:"background-color 0.15s ease"},children:(0,n.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"currentColor",children:(0,n.jsx)("path",{d:"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"})})})]})},re=0,E=()=>`msg_${Date.now()}_${++re}`,W=class{constructor(e){this.collectedData={},this.startStep=e.startStep,this.steps=new Map(e.steps.map(t=>[t.id,t]))}getStartStepId(){return this.startStep}getStep(e){return this.steps.get(e)}getData(){return{...this.collectedData}}setData(e,t){this.collectedData[e]=t}mergeData(e){Object.assign(this.collectedData,e)}resolveNext(e,t){if(e.condition){const{field:r,operator:a,value:l,then:o,else:c}=e.condition,s=this.collectedData[r];return this.evaluate(s,a,l)?o:c}if(t&&e.quickReplies){const r=e.quickReplies.find(a=>a.value===t);if(r?.next)return r.next}return e.next}buildMessages(e){const t=[],r=e.messages??(e.message?[e.message]:[]);for(const a of r)t.push({id:E(),sender:"bot",text:a,timestamp:Date.now()});return e.quickReplies&&t.length>0&&(t[t.length-1].quickReplies=e.quickReplies),e.form&&t.push({id:E(),sender:"bot",timestamp:Date.now(),form:e.form}),t}evaluate(e,t,r){switch(t){case"eq":return String(e)===String(r);case"neq":return String(e)!==String(r);case"contains":return String(e).includes(String(r));case"gt":return Number(e)>Number(r);case"lt":return Number(e)<Number(r);default:return!1}}},ae=0,m=()=>`msg_${Date.now()}_${++ae}`,f=e=>new Promise(t=>setTimeout(t,e));function q(){const{state:e,dispatch:t,props:r}=S(),a=(0,x.useRef)(null),l=(0,x.useRef)(!1);(0,x.useEffect)(()=>{r.flow&&(a.current=new W(r.flow),l.current=!1)},[r.flow]);const o=(0,x.useCallback)(async(u,p)=>{t({type:"SET_TYPING",payload:!0}),await f(400);const h={id:m(),sender:"bot",text:u,timestamp:Date.now(),...p};t({type:"SET_TYPING",payload:!1}),t({type:"ADD_MESSAGE",payload:h}),r.callbacks?.onMessageReceive?.(h)},[t,r.callbacks]),c=(0,x.useCallback)(u=>{const p={id:m(),sender:"user",text:u,timestamp:Date.now()};if(t({type:"ADD_MESSAGE",payload:p}),r.callbacks?.onMessageSend?.(p),r.callbacks?.onSubmit?.({message:u}),a.current&&e.currentStepId){const h=a.current.getStep(e.currentStepId);if(h){a.current.setData(h.id,u);const i=a.current.resolveNext(h,u);i?s(i):(r.callbacks?.onFlowEnd?.(a.current.getData()),t({type:"SET_STEP",payload:null}))}}},[t,r.callbacks,e.currentStepId]),s=(0,x.useCallback)(async u=>{const p=a.current;if(!p)return;const h=p.getStep(u);if(!h)return;t({type:"SET_STEP",payload:u}),t({type:"SET_TYPING",payload:!0}),await f(h.delay??500);const i=p.buildMessages(h);t({type:"SET_TYPING",payload:!1}),t({type:"ADD_MESSAGES",payload:i}),i.forEach(d=>r.callbacks?.onMessageReceive?.(d)),!h.quickReplies&&!h.form&&h.next&&(await f(300),s(h.next))},[t,r.callbacks]),g=(0,x.useCallback)(()=>{const u=a.current;!u||l.current||(l.current=!0,s(u.getStartStepId()))},[s]);return(0,x.useEffect)(()=>{r.flow&&!e.showWelcome&&e.isLoggedIn&&!l.current&&g()},[r.flow,e.showWelcome,e.isLoggedIn,g]),{state:e,sendMessage:c,addBotMessage:o,handleQuickReply:(0,x.useCallback)((u,p)=>{if(t({type:"CLEAR_QUICK_REPLIES"}),t({type:"ADD_MESSAGE",payload:{id:m(),sender:"user",text:p,timestamp:Date.now()}}),r.callbacks?.onQuickReply?.(u,p),a.current&&e.currentStepId){const h=a.current.getStep(e.currentStepId);if(h){a.current.setData(h.id,u);const i=a.current.resolveNext(h,u);i?s(i):(r.callbacks?.onFlowEnd?.(a.current.getData()),t({type:"SET_STEP",payload:null}))}}},[t,r.callbacks,e.currentStepId,s]),handleFormSubmit:(0,x.useCallback)(async(u,p)=>{t({type:"SET_DATA",payload:p}),a.current&&a.current.mergeData(p);const h=Object.entries(p).filter(([,i])=>i!==void 0&&i!=="").map(([i,d])=>`${i}: ${String(d)}`).join(`
7
+ `);if(t({type:"ADD_MESSAGE",payload:{id:m(),sender:"user",text:h,formData:p,timestamp:Date.now()}}),await r.callbacks?.onFormSubmit?.(u,p),a.current&&e.currentStepId){const i=a.current.getStep(e.currentStepId);if(i){const d=a.current.resolveNext(i);d?s(d):(r.callbacks?.onFlowEnd?.(a.current.getData()),t({type:"SET_STEP",payload:null}))}}},[t,r.callbacks,e.currentStepId,s]),handleLogin:(0,x.useCallback)(async u=>{await r.callbacks?.onLogin?.(u),t({type:"SET_LOGGED_IN",payload:!0})},[t,r.callbacks]),toggleChat:(0,x.useCallback)(()=>{const u=!e.isOpen;t({type:"TOGGLE_OPEN"}),u?r.callbacks?.onOpen?.():r.callbacks?.onClose?.()},[t,e.isOpen,r.callbacks]),dismissWelcome:(0,x.useCallback)(()=>{t({type:"DISMISS_WELCOME"})},[t]),startFlow:g,processFlowStep:s}}var N=({styles:e,position:t,zIndex:r})=>{const{props:a}=S(),l=k(a.theme),{state:o,sendMessage:c,handleQuickReply:s,handleFormSubmit:g,handleLogin:u,toggleChat:p,dismissWelcome:h}=q(),i=t==="bottom-left"?{bottom:"90px",left:"20px"}:{bottom:"90px",right:"20px"};return(0,n.jsxs)("div",{style:{...e.window,...i,...r!=null?{zIndex:r}:{}},children:[(0,n.jsx)(F,{config:a.header??{title:"Chat with us"},styles:e,onClose:p}),o.showWelcome&&a.welcomeScreen?(0,n.jsx)(D,{content:a.welcomeScreen,onDismiss:h,primaryColor:l.primaryColor}):!o.isLoggedIn&&a.loginForm?(0,n.jsx)(O,{config:a.loginForm,onLogin:u,primaryColor:l.primaryColor}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(M,{messages:o.messages,isTyping:o.isTyping,styles:e,primaryColor:l.primaryColor,onQuickReply:s,onFormSubmit:g}),(0,n.jsx)("div",{style:e.inputArea,children:(0,n.jsx)(P,{onSend:c,placeholder:a.inputPlaceholder,primaryColor:l.primaryColor})})]})]})},le=e=>{const[t,r]=(0,x.useReducer)(V,e,J),a=Z(k(e.theme),e.style),l=e.position??"bottom-right",o=e.showLauncher!==!1;return(0,n.jsx)(y.Provider,{value:{state:t,dispatch:r,props:e},children:(0,n.jsxs)("div",{style:a.root,className:e.className,children:[t.isOpen&&(0,n.jsx)(N,{styles:a,position:l,zIndex:e.zIndex}),o&&(0,n.jsx)(C,{onClick:()=>{const c=!t.isOpen;r({type:"TOGGLE_OPEN"}),c?e.callbacks?.onOpen?.():e.callbacks?.onClose?.()},isOpen:t.isOpen,position:l,styles:a,icon:e.launcherIcon,closeIcon:e.closeIcon,zIndex:e.zIndex})]})})};exports.ChatBot=le;exports.ChatContext=y;exports.ChatHeader=F;exports.ChatInput=P;exports.ChatWindow=N;exports.CheckboxField=_;exports.DynamicForm=v;exports.FileUploadField=L;exports.FlowEngine=W;exports.Launcher=C;exports.LoginScreen=O;exports.MessageBubble=B;exports.MessageList=M;exports.QuickReplies=z;exports.RadioField=R;exports.SelectField=I;exports.TextField=T;exports.TypingIndicator=A;exports.WelcomeScreen=D;exports.useChat=q;exports.useChatContext=S;
8
+
9
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/context/ChatContext.ts","../src/styles/theme.ts","../src/components/Launcher.tsx","../src/components/ChatHeader.tsx","../src/components/WelcomeScreen.tsx","../src/components/forms/TextField.tsx","../src/components/forms/SelectField.tsx","../src/components/forms/RadioField.tsx","../src/components/forms/CheckboxField.tsx","../src/components/forms/FileUploadField.tsx","../src/components/forms/DynamicForm.tsx","../src/components/LoginScreen.tsx","../src/components/MessageBubble.tsx","../src/components/QuickReplies.tsx","../src/components/TypingIndicator.tsx","../src/components/MessageList.tsx","../src/components/ChatInput.tsx","../src/engine/FlowEngine.ts","../src/utils/helpers.ts","../src/hooks/useChat.ts","../src/components/ChatWindow.tsx","../src/components/ChatBot.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\r\nimport type { ChatMessage, ChatBotProps } from '../types';\r\n\r\nexport interface ChatState {\r\n isOpen: boolean;\r\n messages: ChatMessage[];\r\n isTyping: boolean;\r\n showWelcome: boolean;\r\n currentStepId: string | null;\r\n collectedData: Record<string, unknown>;\r\n isLoggedIn: boolean;\r\n}\r\n\r\nexport type ChatAction =\r\n | { type: 'TOGGLE_OPEN' }\r\n | { type: 'SET_OPEN'; payload: boolean }\r\n | { type: 'ADD_MESSAGE'; payload: ChatMessage }\r\n | { type: 'ADD_MESSAGES'; payload: ChatMessage[] }\r\n | { type: 'SET_TYPING'; payload: boolean }\r\n | { type: 'DISMISS_WELCOME' }\r\n | { type: 'SET_STEP'; payload: string | null }\r\n | { type: 'SET_DATA'; payload: Record<string, unknown> }\r\n | { type: 'SET_LOGGED_IN'; payload: boolean }\r\n | { type: 'CLEAR_QUICK_REPLIES' };\r\n\r\nexport function chatReducer(state: ChatState, action: ChatAction): ChatState {\r\n switch (action.type) {\r\n case 'TOGGLE_OPEN':\r\n return { ...state, isOpen: !state.isOpen };\r\n case 'SET_OPEN':\r\n return { ...state, isOpen: action.payload };\r\n case 'ADD_MESSAGE':\r\n return { ...state, messages: [...state.messages, action.payload] };\r\n case 'ADD_MESSAGES':\r\n return { ...state, messages: [...state.messages, ...action.payload] };\r\n case 'SET_TYPING':\r\n return { ...state, isTyping: action.payload };\r\n case 'DISMISS_WELCOME':\r\n return { ...state, showWelcome: false };\r\n case 'SET_STEP':\r\n return { ...state, currentStepId: action.payload };\r\n case 'SET_DATA':\r\n return { ...state, collectedData: { ...state.collectedData, ...action.payload } };\r\n case 'SET_LOGGED_IN':\r\n return { ...state, isLoggedIn: action.payload };\r\n case 'CLEAR_QUICK_REPLIES':\r\n return {\r\n ...state,\r\n messages: state.messages.map((m) =>\r\n m.quickReplies ? { ...m, quickReplies: undefined } : m,\r\n ),\r\n };\r\n default:\r\n return state;\r\n }\r\n}\r\n\r\nexport const initialState = (props: ChatBotProps): ChatState => ({\r\n isOpen: props.defaultOpen ?? false,\r\n messages: props.initialMessages ?? [],\r\n isTyping: false,\r\n showWelcome: !!props.welcomeScreen,\r\n currentStepId: null,\r\n collectedData: {},\r\n isLoggedIn: !props.loginForm,\r\n});\r\n\r\ninterface ChatContextValue {\r\n state: ChatState;\r\n dispatch: React.Dispatch<ChatAction>;\r\n props: ChatBotProps;\r\n}\r\n\r\nexport const ChatContext = createContext<ChatContextValue | null>(null);\r\n\r\nexport function useChatContext(): ChatContextValue {\r\n const ctx = useContext(ChatContext);\r\n if (!ctx) throw new Error('useChatContext must be used within ChatProvider');\r\n return ctx;\r\n}\r\n","import type { ChatTheme, ChatStyle } from '../types';\r\nimport type { CSSProperties } from 'react';\r\n\r\nconst defaults: Required<ChatTheme> = {\r\n primaryColor: '#0066FF',\r\n headerBg: '#0066FF',\r\n headerText: '#FFFFFF',\r\n bubbleBg: '#F1F1F1',\r\n bubbleText: '#333333',\r\n userBubbleBg: '#0066FF',\r\n userBubbleText: '#FFFFFF',\r\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n fontSize: '14px',\r\n borderRadius: '12px',\r\n windowWidth: '380px',\r\n windowHeight: '550px',\r\n};\r\n\r\nexport function resolveTheme(theme?: ChatTheme): Required<ChatTheme> {\r\n return { ...defaults, ...theme };\r\n}\r\n\r\nexport function buildStyles(\r\n theme: Required<ChatTheme>,\r\n overrides?: ChatStyle,\r\n) {\r\n const styles = {\r\n root: {\r\n fontFamily: theme.fontFamily,\r\n fontSize: theme.fontSize,\r\n lineHeight: '1.5',\r\n } satisfies CSSProperties,\r\n\r\n launcher: {\r\n position: 'fixed',\r\n width: '60px',\r\n height: '60px',\r\n borderRadius: '50%',\r\n backgroundColor: theme.primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n transition: 'transform 0.2s ease',\r\n zIndex: 9998,\r\n ...overrides?.launcher,\r\n } satisfies CSSProperties,\r\n\r\n window: {\r\n position: 'fixed',\r\n width: theme.windowWidth,\r\n height: theme.windowHeight,\r\n maxHeight: '80vh',\r\n borderRadius: theme.borderRadius,\r\n overflow: 'hidden',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n boxShadow: '0 8px 32px rgba(0,0,0,0.15)',\r\n backgroundColor: '#FFFFFF',\r\n zIndex: 9999,\r\n ...overrides?.window,\r\n } satisfies CSSProperties,\r\n\r\n header: {\r\n backgroundColor: theme.headerBg,\r\n color: theme.headerText,\r\n padding: '16px 20px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n flexShrink: 0,\r\n ...overrides?.header,\r\n } satisfies CSSProperties,\r\n\r\n messageList: {\r\n flex: 1,\r\n overflowY: 'auto',\r\n padding: '16px',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px',\r\n ...overrides?.messageList,\r\n } satisfies CSSProperties,\r\n\r\n inputArea: {\r\n padding: '12px 16px',\r\n borderTop: '1px solid #E8E8E8',\r\n display: 'flex',\r\n gap: '8px',\r\n alignItems: 'flex-end',\r\n flexShrink: 0,\r\n ...overrides?.inputArea,\r\n } satisfies CSSProperties,\r\n\r\n botBubble: {\r\n backgroundColor: theme.bubbleBg,\r\n color: theme.bubbleText,\r\n padding: '10px 14px',\r\n borderRadius: '16px 16px 16px 4px',\r\n maxWidth: '80%',\r\n alignSelf: 'flex-start',\r\n wordBreak: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n } satisfies CSSProperties,\r\n\r\n userBubble: {\r\n backgroundColor: theme.userBubbleBg,\r\n color: theme.userBubbleText,\r\n padding: '10px 14px',\r\n borderRadius: '16px 16px 4px 16px',\r\n maxWidth: '80%',\r\n alignSelf: 'flex-end',\r\n wordBreak: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n } satisfies CSSProperties,\r\n };\r\n\r\n return styles;\r\n}\r\n\r\nexport type ChatStyles = ReturnType<typeof buildStyles>;\r\n","import React from 'react';\r\nimport type { CSSProperties } from 'react';\r\nimport type { ChatStyles } from '../styles/theme';\r\n\r\ninterface LauncherProps {\r\n onClick: () => void;\r\n isOpen: boolean;\r\n position: 'bottom-right' | 'bottom-left';\r\n styles: ChatStyles;\r\n icon?: React.ReactNode;\r\n closeIcon?: React.ReactNode;\r\n zIndex?: number;\r\n}\r\n\r\nexport const Launcher: React.FC<LauncherProps> = ({\r\n onClick,\r\n isOpen,\r\n position,\r\n styles,\r\n icon,\r\n closeIcon,\r\n zIndex,\r\n}) => {\r\n const posStyle: CSSProperties =\r\n position === 'bottom-left'\r\n ? { bottom: '20px', left: '20px' }\r\n : { bottom: '20px', right: '20px' };\r\n\r\n return (\r\n <button\r\n onClick={onClick}\r\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\r\n style={{\r\n ...styles.launcher,\r\n ...posStyle,\r\n ...(zIndex != null ? { zIndex } : {}),\r\n transform: isOpen ? 'scale(0.9)' : 'scale(1)',\r\n }}\r\n >\r\n {isOpen\r\n ? closeIcon ?? <CloseIcon />\r\n : icon ?? <ChatIcon />}\r\n </button>\r\n );\r\n};\r\n\r\nconst ChatIcon: React.FC = () => (\r\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\r\n </svg>\r\n);\r\n\r\nconst CloseIcon: React.FC = () => (\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n","import React from 'react';\r\nimport type { HeaderConfig } from '../types';\r\nimport type { ChatStyles as ThemeStyles } from '../styles/theme';\r\n\r\ninterface ChatHeaderProps {\r\n config: HeaderConfig;\r\n styles: ThemeStyles;\r\n onClose: () => void;\r\n}\r\n\r\nexport const ChatHeader: React.FC<ChatHeaderProps> = ({ config, styles, onClose }) => {\r\n return (\r\n <div style={styles.header}>\r\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px', flex: 1 }}>\r\n {config.avatar && (\r\n <img\r\n src={config.avatar}\r\n alt=\"\"\r\n style={{ width: '36px', height: '36px', borderRadius: '50%', objectFit: 'cover' }}\r\n />\r\n )}\r\n <div>\r\n <div style={{ fontWeight: 600, fontSize: '15px' }}>\r\n {config.title ?? 'Chat with us'}\r\n </div>\r\n {config.subtitle && (\r\n <div style={{ fontSize: '12px', opacity: 0.85 }}>{config.subtitle}</div>\r\n )}\r\n </div>\r\n </div>\r\n {config.showClose !== false && (\r\n <button\r\n onClick={onClose}\r\n aria-label=\"Close chat\"\r\n style={{\r\n background: 'none',\r\n border: 'none',\r\n color: 'inherit',\r\n cursor: 'pointer',\r\n padding: '4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { ReactNode } from 'react';\r\n\r\ninterface WelcomeScreenProps {\r\n content: ReactNode;\r\n onDismiss: () => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const WelcomeScreen: React.FC<WelcomeScreenProps> = ({ content, onDismiss, primaryColor }) => {\r\n return (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'auto',\r\n }}\r\n >\r\n <div style={{ flex: 1, padding: '20px', overflow: 'auto' }}>\r\n {content}\r\n </div>\r\n <div style={{ padding: '12px 16px', borderTop: '1px solid #E8E8E8', flexShrink: 0 }}>\r\n <button\r\n onClick={onDismiss}\r\n style={{\r\n width: '100%',\r\n padding: '12px',\r\n backgroundColor: primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n }}\r\n >\r\n Start Chat\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface TextFieldProps {\r\n field: FormFieldConfig;\r\n value: string;\r\n onChange: (value: string) => void;\r\n error?: string;\r\n}\r\n\r\nexport const TextField: React.FC<TextFieldProps> = ({ field, value, onChange, error }) => {\r\n const isTextarea = field.type === 'textarea';\r\n const inputType = field.type === 'textarea' ? undefined : field.type;\r\n\r\n const baseStyle: React.CSSProperties = {\r\n width: '100%',\r\n padding: '8px 12px',\r\n border: `1px solid ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n fontFamily: 'inherit',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.15s ease',\r\n };\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n {isTextarea ? (\r\n <textarea\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n rows={3}\r\n style={{ ...baseStyle, resize: 'vertical' }}\r\n minLength={field.validation?.minLength}\r\n maxLength={field.validation?.maxLength}\r\n />\r\n ) : (\r\n <input\r\n type={inputType}\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n style={baseStyle}\r\n min={field.validation?.min}\r\n max={field.validation?.max}\r\n minLength={field.validation?.minLength}\r\n maxLength={field.validation?.maxLength}\r\n pattern={field.validation?.pattern}\r\n />\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface SelectFieldProps {\r\n field: FormFieldConfig;\r\n value: string | string[];\r\n onChange: (value: string | string[]) => void;\r\n error?: string;\r\n}\r\n\r\nexport const SelectField: React.FC<SelectFieldProps> = ({ field, value, onChange, error }) => {\r\n const isMulti = field.type === 'multiselect' || field.multiple;\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\r\n if (isMulti) {\r\n const selected = Array.from(e.target.selectedOptions, (opt) => opt.value);\r\n onChange(selected);\r\n } else {\r\n onChange(e.target.value);\r\n }\r\n };\r\n\r\n const selectValue = isMulti\r\n ? Array.isArray(value) ? value : [value].filter(Boolean)\r\n : typeof value === 'string' ? value : '';\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <select\r\n value={selectValue}\r\n onChange={handleChange}\r\n multiple={isMulti}\r\n required={field.required}\r\n style={{\r\n width: '100%',\r\n padding: '8px 12px',\r\n border: `1px solid ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n fontFamily: 'inherit',\r\n outline: 'none',\r\n backgroundColor: '#fff',\r\n boxSizing: 'border-box',\r\n ...(isMulti ? { minHeight: '80px' } : {}),\r\n }}\r\n >\r\n {!isMulti && <option value=\"\">Select...</option>}\r\n {field.options?.map((opt) => (\r\n <option key={opt.value} value={opt.value}>\r\n {opt.label}\r\n </option>\r\n ))}\r\n </select>\r\n {isMulti && (\r\n <div style={{ fontSize: '11px', color: '#888', marginTop: '2px' }}>\r\n Hold Ctrl/Cmd to select multiple\r\n </div>\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface RadioFieldProps {\r\n field: FormFieldConfig;\r\n value: string;\r\n onChange: (value: string) => void;\r\n error?: string;\r\n}\r\n\r\nexport const RadioField: React.FC<RadioFieldProps> = ({ field, value, onChange, error }) => {\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '6px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\r\n {field.options?.map((opt) => (\r\n <label\r\n key={opt.value}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n }}\r\n >\r\n <input\r\n type=\"radio\"\r\n name={field.name}\r\n value={opt.value}\r\n checked={value === opt.value}\r\n onChange={() => onChange(opt.value)}\r\n style={{ margin: 0 }}\r\n />\r\n {opt.label}\r\n </label>\r\n ))}\r\n </div>\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface CheckboxFieldProps {\r\n field: FormFieldConfig;\r\n value: string[];\r\n onChange: (value: string[]) => void;\r\n error?: string;\r\n}\r\n\r\nexport const CheckboxField: React.FC<CheckboxFieldProps> = ({ field, value, onChange, error }) => {\r\n const handleToggle = (optValue: string) => {\r\n if (value.includes(optValue)) {\r\n onChange(value.filter((v) => v !== optValue));\r\n } else {\r\n onChange([...value, optValue]);\r\n }\r\n };\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '6px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\r\n {field.options?.map((opt) => (\r\n <label\r\n key={opt.value}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n }}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={value.includes(opt.value)}\r\n onChange={() => handleToggle(opt.value)}\r\n style={{ margin: 0 }}\r\n />\r\n {opt.label}\r\n </label>\r\n ))}\r\n </div>\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React, { useRef } from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface FileUploadFieldProps {\r\n field: FormFieldConfig;\r\n value: FileList | null;\r\n onChange: (files: FileList | null) => void;\r\n error?: string;\r\n primaryColor: string;\r\n}\r\n\r\nexport const FileUploadField: React.FC<FileUploadFieldProps> = ({\r\n field,\r\n value,\r\n onChange,\r\n error,\r\n primaryColor,\r\n}) => {\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n const fileNames = value ? Array.from(value).map((f) => f.name).join(', ') : '';\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <input\r\n ref={inputRef}\r\n type=\"file\"\r\n accept={field.accept}\r\n multiple={field.multiple}\r\n onChange={(e) => onChange(e.target.files)}\r\n style={{ display: 'none' }}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => inputRef.current?.click()}\r\n style={{\r\n padding: '8px 16px',\r\n border: `1px dashed ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n backgroundColor: '#FAFAFA',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n color: '#555',\r\n width: '100%',\r\n textAlign: 'left',\r\n }}\r\n >\r\n {fileNames || field.placeholder || 'Choose file(s)...'}\r\n </button>\r\n {fileNames && (\r\n <div style={{ fontSize: '12px', color: primaryColor, marginTop: '4px' }}>\r\n {Array.from(value!).length} file(s) selected\r\n </div>\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React, { useState, useCallback } from 'react';\r\nimport type { FormConfig, FormFieldConfig } from '../../types';\r\nimport { TextField } from './TextField';\r\nimport { SelectField } from './SelectField';\r\nimport { RadioField } from './RadioField';\r\nimport { CheckboxField } from './CheckboxField';\r\nimport { FileUploadField } from './FileUploadField';\r\n\r\ninterface DynamicFormProps {\r\n config: FormConfig;\r\n onSubmit: (data: Record<string, unknown>) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const DynamicForm: React.FC<DynamicFormProps> = ({ config, onSubmit, primaryColor }) => {\r\n const [values, setValues] = useState<Record<string, unknown>>(() => {\r\n const init: Record<string, unknown> = {};\r\n for (const field of config.fields) {\r\n if (field.defaultValue !== undefined) {\r\n init[field.name] = field.defaultValue;\r\n } else if (field.type === 'checkbox' || field.type === 'multiselect') {\r\n init[field.name] = [];\r\n } else if (field.type === 'file') {\r\n init[field.name] = null;\r\n } else {\r\n init[field.name] = '';\r\n }\r\n }\r\n return init;\r\n });\r\n\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n const [submitted, setSubmitted] = useState(false);\r\n\r\n const setValue = useCallback((name: string, value: unknown) => {\r\n setValues((prev) => ({ ...prev, [name]: value }));\r\n setErrors((prev) => {\r\n const next = { ...prev };\r\n delete next[name];\r\n return next;\r\n });\r\n }, []);\r\n\r\n const validate = (): boolean => {\r\n const newErrors: Record<string, string> = {};\r\n\r\n for (const field of config.fields) {\r\n const val = values[field.name];\r\n\r\n // Required check\r\n if (field.required) {\r\n if (\r\n val === '' ||\r\n val === null ||\r\n val === undefined ||\r\n (Array.isArray(val) && val.length === 0)\r\n ) {\r\n newErrors[field.name] = field.validation?.message ?? `${field.label || field.name} is required`;\r\n continue;\r\n }\r\n }\r\n\r\n // Pattern check\r\n if (field.validation?.pattern && typeof val === 'string' && val) {\r\n const regex = new RegExp(field.validation.pattern);\r\n if (!regex.test(val)) {\r\n newErrors[field.name] = field.validation.message ?? 'Invalid format';\r\n }\r\n }\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!validate()) return;\r\n setSubmitted(true);\r\n onSubmit(values);\r\n };\r\n\r\n if (submitted) {\r\n return (\r\n <div\r\n style={{\r\n padding: '12px',\r\n backgroundColor: '#F0FFF4',\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n color: '#276749',\r\n textAlign: 'center',\r\n }}\r\n >\r\n Submitted successfully\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <form\r\n onSubmit={handleSubmit}\r\n style={{\r\n backgroundColor: '#FAFAFA',\r\n borderRadius: '10px',\r\n padding: '16px',\r\n border: '1px solid #E8E8E8',\r\n }}\r\n >\r\n {config.title && (\r\n <div style={{ fontWeight: 600, fontSize: '14px', marginBottom: '4px' }}>\r\n {config.title}\r\n </div>\r\n )}\r\n {config.description && (\r\n <div style={{ fontSize: '12px', color: '#888', marginBottom: '12px' }}>\r\n {config.description}\r\n </div>\r\n )}\r\n\r\n {config.fields.map((field) => (\r\n <FormField\r\n key={field.name}\r\n field={field}\r\n value={values[field.name]}\r\n onChange={(v) => setValue(field.name, v)}\r\n error={errors[field.name]}\r\n primaryColor={primaryColor}\r\n />\r\n ))}\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: '100%',\r\n padding: '10px',\r\n backgroundColor: primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n marginTop: '4px',\r\n }}\r\n >\r\n {config.submitLabel ?? 'Submit'}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\n// ─── Field Router ────────────────────────────────────────────────\r\n\r\ninterface FormFieldProps {\r\n field: FormFieldConfig;\r\n value: unknown;\r\n onChange: (value: unknown) => void;\r\n error?: string;\r\n primaryColor: string;\r\n}\r\n\r\nconst FormField: React.FC<FormFieldProps> = ({ field, value, onChange, error, primaryColor }) => {\r\n switch (field.type) {\r\n case 'text':\r\n case 'email':\r\n case 'password':\r\n case 'number':\r\n case 'tel':\r\n case 'url':\r\n case 'textarea':\r\n case 'date':\r\n case 'time':\r\n return (\r\n <TextField\r\n field={field}\r\n value={String(value ?? '')}\r\n onChange={onChange as (v: string) => void}\r\n error={error}\r\n />\r\n );\r\n case 'select':\r\n case 'multiselect':\r\n return (\r\n <SelectField\r\n field={field}\r\n value={value as string | string[]}\r\n onChange={onChange as (v: string | string[]) => void}\r\n error={error}\r\n />\r\n );\r\n case 'radio':\r\n return (\r\n <RadioField\r\n field={field}\r\n value={String(value ?? '')}\r\n onChange={onChange as (v: string) => void}\r\n error={error}\r\n />\r\n );\r\n case 'checkbox':\r\n return (\r\n <CheckboxField\r\n field={field}\r\n value={(value as string[]) ?? []}\r\n onChange={onChange as (v: string[]) => void}\r\n error={error}\r\n />\r\n );\r\n case 'file':\r\n return (\r\n <FileUploadField\r\n field={field}\r\n value={value as FileList | null}\r\n onChange={onChange as (v: FileList | null) => void}\r\n error={error}\r\n primaryColor={primaryColor}\r\n />\r\n );\r\n case 'hidden':\r\n return <input type=\"hidden\" name={field.name} value={String(value ?? '')} />;\r\n default:\r\n return null;\r\n }\r\n};\r\n","import React from 'react';\r\nimport type { FormConfig } from '../types';\r\nimport { DynamicForm } from './forms/DynamicForm';\r\n\r\ninterface LoginScreenProps {\r\n config: FormConfig;\r\n onLogin: (data: Record<string, unknown>) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const LoginScreen: React.FC<LoginScreenProps> = ({ config, onLogin, primaryColor }) => {\r\n return (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '20px',\r\n overflow: 'auto',\r\n }}\r\n >\r\n <DynamicForm config={config} onSubmit={onLogin} primaryColor={primaryColor} />\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { ChatMessage } from '../types';\r\nimport type { ChatStyles } from '../styles/theme';\r\n\r\ninterface MessageBubbleProps {\r\n message: ChatMessage;\r\n styles: ChatStyles;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message, styles }) => {\r\n const isBot = message.sender === 'bot';\r\n const bubbleStyle = isBot ? styles.botBubble : styles.userBubble;\r\n\r\n if (!message.text && !message.attachment) return null;\r\n\r\n return (\r\n <div style={bubbleStyle}>\r\n {message.text && <span>{message.text}</span>}\r\n {message.attachment && (\r\n <div style={{ marginTop: message.text ? '6px' : 0 }}>\r\n <a\r\n href={message.attachment.url}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n style={{ color: 'inherit', textDecoration: 'underline', fontSize: '13px' }}\r\n >\r\n 📎 {message.attachment.name}\r\n </a>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FlowQuickReply } from '../types';\r\n\r\ninterface QuickRepliesProps {\r\n replies: FlowQuickReply[];\r\n onSelect: (value: string, label: string) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const QuickReplies: React.FC<QuickRepliesProps> = ({ replies, onSelect, primaryColor }) => {\r\n return (\r\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignSelf: 'flex-start', maxWidth: '90%' }}>\r\n {replies.map((reply) => (\r\n <button\r\n key={reply.value}\r\n onClick={() => onSelect(reply.value, reply.label)}\r\n style={{\r\n padding: '6px 14px',\r\n borderRadius: '18px',\r\n border: `1px solid ${primaryColor}`,\r\n backgroundColor: 'transparent',\r\n color: primaryColor,\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n fontWeight: 500,\r\n transition: 'all 0.15s ease',\r\n }}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.backgroundColor = primaryColor;\r\n e.currentTarget.style.color = '#fff';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.backgroundColor = 'transparent';\r\n e.currentTarget.style.color = primaryColor;\r\n }}\r\n >\r\n {reply.label}\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\n\r\ninterface TypingIndicatorProps {\r\n color: string;\r\n}\r\n\r\nexport const TypingIndicator: React.FC<TypingIndicatorProps> = ({ color }) => {\r\n const dotStyle: React.CSSProperties = {\r\n width: '8px',\r\n height: '8px',\r\n borderRadius: '50%',\r\n backgroundColor: color,\r\n opacity: 0.4,\r\n animation: 'chatbot-typing-bounce 1.4s infinite ease-in-out',\r\n };\r\n\r\n return (\r\n <>\r\n <style>{`\r\n @keyframes chatbot-typing-bounce {\r\n 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }\r\n 40% { transform: scale(1); opacity: 1; }\r\n }\r\n `}</style>\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: '4px',\r\n padding: '12px 16px',\r\n backgroundColor: '#F1F1F1',\r\n borderRadius: '16px 16px 16px 4px',\r\n alignSelf: 'flex-start',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <span style={{ ...dotStyle, animationDelay: '0s' }} />\r\n <span style={{ ...dotStyle, animationDelay: '0.2s' }} />\r\n <span style={{ ...dotStyle, animationDelay: '0.4s' }} />\r\n </div>\r\n </>\r\n );\r\n};\r\n","import React, { useRef, useEffect } from 'react';\r\nimport type { ChatMessage } from '../types';\r\nimport type { ChatStyles } from '../styles/theme';\r\nimport { MessageBubble } from './MessageBubble';\r\nimport { QuickReplies } from './QuickReplies';\r\nimport { TypingIndicator } from './TypingIndicator';\r\nimport { DynamicForm } from './forms/DynamicForm';\r\n\r\ninterface MessageListProps {\r\n messages: ChatMessage[];\r\n isTyping: boolean;\r\n styles: ChatStyles;\r\n primaryColor: string;\r\n onQuickReply: (value: string, label: string) => void;\r\n onFormSubmit: (formId: string, data: Record<string, unknown>) => void;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({\r\n messages,\r\n isTyping,\r\n styles,\r\n primaryColor,\r\n onQuickReply,\r\n onFormSubmit,\r\n}) => {\r\n const bottomRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isTyping]);\r\n\r\n return (\r\n <div style={styles.messageList}>\r\n {messages.map((msg) => (\r\n <React.Fragment key={msg.id}>\r\n <MessageBubble message={msg} styles={styles} />\r\n {msg.quickReplies && msg.quickReplies.length > 0 && (\r\n <QuickReplies\r\n replies={msg.quickReplies}\r\n onSelect={onQuickReply}\r\n primaryColor={primaryColor}\r\n />\r\n )}\r\n {msg.form && (\r\n <div style={{ alignSelf: 'flex-start', width: '90%' }}>\r\n <DynamicForm\r\n config={msg.form}\r\n onSubmit={(data) => onFormSubmit(msg.form!.id, data)}\r\n primaryColor={primaryColor}\r\n />\r\n </div>\r\n )}\r\n </React.Fragment>\r\n ))}\r\n {isTyping && <TypingIndicator color={primaryColor} />}\r\n <div ref={bottomRef} />\r\n </div>\r\n );\r\n};\r\n","import React, { useState, useRef } from 'react';\r\nimport type { CSSProperties } from 'react';\r\n\r\ninterface ChatInputProps {\r\n onSend: (text: string) => void;\r\n placeholder?: string;\r\n primaryColor: string;\r\n disabled?: boolean;\r\n styleOverride?: CSSProperties;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({\r\n onSend,\r\n placeholder = 'Type a message...',\r\n primaryColor,\r\n disabled,\r\n styleOverride,\r\n}) => {\r\n const [text, setText] = useState('');\r\n const inputRef = useRef<HTMLTextAreaElement>(null);\r\n\r\n const handleSend = () => {\r\n const trimmed = text.trim();\r\n if (!trimmed) return;\r\n onSend(trimmed);\r\n setText('');\r\n inputRef.current?.focus();\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div style={{ display: 'flex', gap: '8px', alignItems: 'flex-end', ...styleOverride }}>\r\n <textarea\r\n ref={inputRef}\r\n value={text}\r\n onChange={(e) => setText(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n rows={1}\r\n style={{\r\n flex: 1,\r\n padding: '10px 14px',\r\n border: '1px solid #E0E0E0',\r\n borderRadius: '20px',\r\n outline: 'none',\r\n resize: 'none',\r\n fontFamily: 'inherit',\r\n fontSize: '14px',\r\n lineHeight: '1.4',\r\n maxHeight: '100px',\r\n overflowY: 'auto',\r\n }}\r\n />\r\n <button\r\n onClick={handleSend}\r\n disabled={disabled || !text.trim()}\r\n aria-label=\"Send message\"\r\n style={{\r\n width: '38px',\r\n height: '38px',\r\n borderRadius: '50%',\r\n backgroundColor: text.trim() ? primaryColor : '#CCC',\r\n color: '#fff',\r\n border: 'none',\r\n cursor: text.trim() ? 'pointer' : 'default',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n flexShrink: 0,\r\n transition: 'background-color 0.15s ease',\r\n }}\r\n >\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import type { FlowConfig, FlowStep, ChatMessage, FlowQuickReply } from '../types';\r\n\r\nlet idCounter = 0;\r\nconst uid = (): string => `msg_${Date.now()}_${++idCounter}`;\r\n\r\nexport class FlowEngine {\r\n private steps: Map<string, FlowStep>;\r\n private startStep: string;\r\n private collectedData: Record<string, unknown> = {};\r\n\r\n constructor(flow: FlowConfig) {\r\n this.startStep = flow.startStep;\r\n this.steps = new Map(flow.steps.map((s) => [s.id, s]));\r\n }\r\n\r\n getStartStepId(): string {\r\n return this.startStep;\r\n }\r\n\r\n getStep(id: string): FlowStep | undefined {\r\n return this.steps.get(id);\r\n }\r\n\r\n getData(): Record<string, unknown> {\r\n return { ...this.collectedData };\r\n }\r\n\r\n setData(key: string, value: unknown): void {\r\n this.collectedData[key] = value;\r\n }\r\n\r\n mergeData(data: Record<string, unknown>): void {\r\n Object.assign(this.collectedData, data);\r\n }\r\n\r\n resolveNext(step: FlowStep, userValue?: string): string | undefined {\r\n // Conditional branching\r\n if (step.condition) {\r\n const { field, operator, value, then: thenStep, else: elseStep } = step.condition;\r\n const fieldVal = this.collectedData[field];\r\n const match = this.evaluate(fieldVal, operator, value);\r\n return match ? thenStep : elseStep;\r\n }\r\n\r\n // Quick-reply selected → find the reply's next\r\n if (userValue && step.quickReplies) {\r\n const reply = step.quickReplies.find((r) => r.value === userValue);\r\n if (reply?.next) return reply.next;\r\n }\r\n\r\n return step.next;\r\n }\r\n\r\n buildMessages(step: FlowStep): ChatMessage[] {\r\n const messages: ChatMessage[] = [];\r\n\r\n const texts = step.messages ?? (step.message ? [step.message] : []);\r\n for (const text of texts) {\r\n messages.push({\r\n id: uid(),\r\n sender: 'bot',\r\n text,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n // Attach quick replies to the last message\r\n if (step.quickReplies && messages.length > 0) {\r\n messages[messages.length - 1]!.quickReplies = step.quickReplies;\r\n }\r\n\r\n // If step has a form, create a form message\r\n if (step.form) {\r\n messages.push({\r\n id: uid(),\r\n sender: 'bot',\r\n timestamp: Date.now(),\r\n form: step.form,\r\n });\r\n }\r\n\r\n return messages;\r\n }\r\n\r\n private evaluate(\r\n fieldVal: unknown,\r\n operator: string,\r\n value: string | number,\r\n ): boolean {\r\n switch (operator) {\r\n case 'eq':\r\n return String(fieldVal) === String(value);\r\n case 'neq':\r\n return String(fieldVal) !== String(value);\r\n case 'contains':\r\n return String(fieldVal).includes(String(value));\r\n case 'gt':\r\n return Number(fieldVal) > Number(value);\r\n case 'lt':\r\n return Number(fieldVal) < Number(value);\r\n default:\r\n return false;\r\n }\r\n }\r\n}\r\n\r\nexport function createQuickReplyMessage(\r\n replies: FlowQuickReply[],\r\n): ChatMessage {\r\n return {\r\n id: uid(),\r\n sender: 'bot',\r\n timestamp: Date.now(),\r\n quickReplies: replies,\r\n };\r\n}\r\n","let counter = 0;\r\n\r\nexport const uid = (): string => `msg_${Date.now()}_${++counter}`;\r\n\r\nexport const classNames = (...args: (string | false | null | undefined)[]): string =>\r\n args.filter(Boolean).join(' ');\r\n\r\nexport const delay = (ms: number): Promise<void> =>\r\n new Promise((resolve) => setTimeout(resolve, ms));\r\n","import { useCallback, useRef, useEffect } from 'react';\r\nimport { useChatContext } from '../context/ChatContext';\r\nimport { FlowEngine } from '../engine/FlowEngine';\r\nimport { uid, delay } from '../utils/helpers';\r\nimport type { ChatMessage, FormConfig } from '../types';\r\n\r\nexport function useChat() {\r\n const { state, dispatch, props } = useChatContext();\r\n const flowRef = useRef<FlowEngine | null>(null);\r\n const flowStartedRef = useRef(false);\r\n\r\n // Initialize flow engine\r\n useEffect(() => {\r\n if (props.flow) {\r\n flowRef.current = new FlowEngine(props.flow);\r\n flowStartedRef.current = false;\r\n }\r\n }, [props.flow]);\r\n\r\n const addBotMessage = useCallback(\r\n async (text: string, extras?: Partial<ChatMessage>) => {\r\n dispatch({ type: 'SET_TYPING', payload: true });\r\n await delay(400);\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'bot',\r\n text,\r\n timestamp: Date.now(),\r\n ...extras,\r\n };\r\n dispatch({ type: 'SET_TYPING', payload: false });\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onMessageReceive?.(msg);\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const sendMessage = useCallback(\r\n (text: string) => {\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onMessageSend?.(msg);\r\n props.callbacks?.onSubmit?.({ message: text });\r\n\r\n // Process flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n flowRef.current.setData(step.id, text);\r\n const nextId = flowRef.current.resolveNext(step, text);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId],\r\n );\r\n\r\n const processFlowStep = useCallback(\r\n async (stepId: string) => {\r\n const engine = flowRef.current;\r\n if (!engine) return;\r\n\r\n const step = engine.getStep(stepId);\r\n if (!step) return;\r\n\r\n dispatch({ type: 'SET_STEP', payload: stepId });\r\n dispatch({ type: 'SET_TYPING', payload: true });\r\n await delay(step.delay ?? 500);\r\n\r\n const messages = engine.buildMessages(step);\r\n dispatch({ type: 'SET_TYPING', payload: false });\r\n dispatch({ type: 'ADD_MESSAGES', payload: messages });\r\n\r\n messages.forEach((m) => props.callbacks?.onMessageReceive?.(m));\r\n\r\n // Auto-advance if no user input required\r\n if (!step.quickReplies && !step.form && step.next) {\r\n await delay(300);\r\n processFlowStep(step.next);\r\n }\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const startFlow = useCallback(() => {\r\n const engine = flowRef.current;\r\n if (!engine || flowStartedRef.current) return;\r\n flowStartedRef.current = true;\r\n processFlowStep(engine.getStartStepId());\r\n }, [processFlowStep]);\r\n\r\n // Auto-start flow when all conditions are met\r\n useEffect(() => {\r\n if (\r\n props.flow &&\r\n !state.showWelcome &&\r\n state.isLoggedIn &&\r\n !flowStartedRef.current\r\n ) {\r\n startFlow();\r\n }\r\n }, [props.flow, state.showWelcome, state.isLoggedIn, startFlow]);\r\n\r\n const handleQuickReply = useCallback(\r\n (value: string, label: string) => {\r\n dispatch({ type: 'CLEAR_QUICK_REPLIES' });\r\n // Add user message\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text: label,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onQuickReply?.(value, label);\r\n\r\n // Continue flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n flowRef.current.setData(step.id, value);\r\n const nextId = flowRef.current.resolveNext(step, value);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId, processFlowStep],\r\n );\r\n\r\n const handleFormSubmit = useCallback(\r\n async (formId: string, data: Record<string, unknown>) => {\r\n dispatch({ type: 'SET_DATA', payload: data });\r\n if (flowRef.current) {\r\n flowRef.current.mergeData(data);\r\n }\r\n\r\n // Summary message\r\n const summaryLines = Object.entries(data)\r\n .filter(([, v]) => v !== undefined && v !== '')\r\n .map(([k, v]) => `${k}: ${String(v)}`)\r\n .join('\\n');\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text: summaryLines,\r\n formData: data,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n\r\n await props.callbacks?.onFormSubmit?.(formId, data);\r\n\r\n // Advance flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n const nextId = flowRef.current.resolveNext(step);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId, processFlowStep],\r\n );\r\n\r\n const handleLogin = useCallback(\r\n async (data: Record<string, unknown>) => {\r\n await props.callbacks?.onLogin?.(data);\r\n dispatch({ type: 'SET_LOGGED_IN', payload: true });\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const toggleChat = useCallback(() => {\r\n const willOpen = !state.isOpen;\r\n dispatch({ type: 'TOGGLE_OPEN' });\r\n if (willOpen) {\r\n props.callbacks?.onOpen?.();\r\n } else {\r\n props.callbacks?.onClose?.();\r\n }\r\n }, [dispatch, state.isOpen, props.callbacks]);\r\n\r\n const dismissWelcome = useCallback(() => {\r\n dispatch({ type: 'DISMISS_WELCOME' });\r\n }, [dispatch]);\r\n\r\n return {\r\n state,\r\n sendMessage,\r\n addBotMessage,\r\n handleQuickReply,\r\n handleFormSubmit,\r\n handleLogin,\r\n toggleChat,\r\n dismissWelcome,\r\n startFlow,\r\n processFlowStep,\r\n };\r\n}\r\n","import React from 'react';\r\nimport type { CSSProperties } from 'react';\r\nimport type { ChatStyles } from '../styles/theme';\r\nimport { ChatHeader } from './ChatHeader';\r\nimport { WelcomeScreen } from './WelcomeScreen';\r\nimport { LoginScreen } from './LoginScreen';\r\nimport { MessageList } from './MessageList';\r\nimport { ChatInput } from './ChatInput';\r\nimport { useChat } from '../hooks/useChat';\r\nimport { useChatContext } from '../context/ChatContext';\r\nimport { resolveTheme } from '../styles/theme';\r\n\r\ninterface ChatWindowProps {\r\n styles: ChatStyles;\r\n position: 'bottom-right' | 'bottom-left';\r\n zIndex?: number;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({ styles, position, zIndex }) => {\r\n const { props } = useChatContext();\r\n const theme = resolveTheme(props.theme);\r\n const {\r\n state,\r\n sendMessage,\r\n handleQuickReply,\r\n handleFormSubmit,\r\n handleLogin,\r\n toggleChat,\r\n dismissWelcome,\r\n } = useChat();\r\n\r\n const posStyle: CSSProperties =\r\n position === 'bottom-left'\r\n ? { bottom: '90px', left: '20px' }\r\n : { bottom: '90px', right: '20px' };\r\n\r\n return (\r\n <div\r\n style={{\r\n ...styles.window,\r\n ...posStyle,\r\n ...(zIndex != null ? { zIndex } : {}),\r\n }}\r\n >\r\n <ChatHeader\r\n config={props.header ?? { title: 'Chat with us' }}\r\n styles={styles}\r\n onClose={toggleChat}\r\n />\r\n\r\n {/* Welcome Screen */}\r\n {state.showWelcome && props.welcomeScreen ? (\r\n <WelcomeScreen\r\n content={props.welcomeScreen}\r\n onDismiss={dismissWelcome}\r\n primaryColor={theme.primaryColor}\r\n />\r\n ) : /* Login Screen */\r\n !state.isLoggedIn && props.loginForm ? (\r\n <LoginScreen\r\n config={props.loginForm}\r\n onLogin={handleLogin}\r\n primaryColor={theme.primaryColor}\r\n />\r\n ) : (\r\n /* Chat Area */\r\n <>\r\n <MessageList\r\n messages={state.messages}\r\n isTyping={state.isTyping}\r\n styles={styles}\r\n primaryColor={theme.primaryColor}\r\n onQuickReply={handleQuickReply}\r\n onFormSubmit={handleFormSubmit}\r\n />\r\n <div style={styles.inputArea}>\r\n <ChatInput\r\n onSend={sendMessage}\r\n placeholder={props.inputPlaceholder}\r\n primaryColor={theme.primaryColor}\r\n />\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useReducer } from 'react';\r\nimport type { ChatBotProps } from '../types';\r\nimport { ChatContext, chatReducer, initialState } from '../context/ChatContext';\r\nimport { resolveTheme, buildStyles } from '../styles/theme';\r\nimport { Launcher } from './Launcher';\r\nimport { ChatWindow } from './ChatWindow';\r\n\r\nexport const ChatBot: React.FC<ChatBotProps> = (props) => {\r\n const [state, dispatch] = useReducer(chatReducer, props, initialState);\r\n const theme = resolveTheme(props.theme);\r\n const styles = buildStyles(theme, props.style);\r\n const position = props.position ?? 'bottom-right';\r\n const showLauncher = props.showLauncher !== false;\r\n\r\n\r\n\r\n return (\r\n <ChatContext.Provider value={{ state, dispatch, props }}>\r\n <div style={styles.root} className={props.className}>\r\n {state.isOpen && (\r\n <ChatWindow styles={styles} position={position} zIndex={props.zIndex} />\r\n )}\r\n {showLauncher && (\r\n <Launcher\r\n onClick={() => {\r\n const willOpen = !state.isOpen;\r\n dispatch({ type: 'TOGGLE_OPEN' });\r\n if (willOpen) props.callbacks?.onOpen?.();\r\n else props.callbacks?.onClose?.();\r\n }}\r\n isOpen={state.isOpen}\r\n position={position}\r\n styles={styles}\r\n icon={props.launcherIcon}\r\n closeIcon={props.closeIcon}\r\n zIndex={props.zIndex}\r\n />\r\n )}\r\n </div>\r\n </ChatContext.Provider>\r\n );\r\n};\r\n"],"mappings":"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"}