@kitn.ai/ui
Version:
Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.
15 lines (14 loc) • 2.93 kB
JavaScript
import{g as k,p as j,s as A,h as b,l as D,i as v,c as C,F as E,a as I,b as z,z as F,n as G,S as H,t as x,f as J}from"./chunks/define-CNSKFZCd.js";import{c as K}from"./chunks/cn-CU7UAWzk.js";function L(t){const e=t.speed??20,y=t.characterChunkSize??3,[f,i]=k(""),[S,u]=k(!0),[a,n]=k([]);let s="",d=0,m,o=!1,r;function l(){m!==void 0&&(clearInterval(m),m=void 0)}function p(){if(!o){if(d>=s.length){r||(l(),u(!0));return}d=Math.min(d+y,s.length),i(s.slice(0,d))}}async function $(c){r=c[Symbol.asyncIterator]();try{for(;;){const{value:h,done:M}=await r.next();if(M)break;h&&(s+=h,n(g=>[...g,{text:h,index:g.length}]))}}finally{r=void 0}}function q(c){if(w(),u(!1),typeof c=="string")if(s=c,t.mode==="typewriter")m=setInterval(p,e);else{const h=c.split(/(\s+)/).filter(Boolean);n(h.map((M,g)=>({text:M,index:g}))),i(c)}else t.mode==="typewriter"&&(m=setInterval(p,e)),$(c).then(()=>{t.mode==="fade"&&(i(s),u(!0))})}function T(){o=!0}function B(){o=!1}function w(){l(),s="",d=0,o=!1,r=void 0,i(""),u(!0),n([])}return j(()=>l()),{displayedText:f,isComplete:S,segments:a,startStreaming:q,pause:T,resume:B,reset:w}}var N=x("<style>"),P=x("<div class=relative>"),R=x("<div>"),W=x("<span>");function _(t){const[e]=A(t,["textStream","mode","speed","class","onComplete","as","fadeDuration","segmentDelay","characterChunkSize"]),y=()=>e.mode??"typewriter",f=()=>e.speed??20,i=L({mode:y(),speed:f(),characterChunkSize:e.characterChunkSize,fadeDuration:e.fadeDuration});b(D(()=>e.textStream,a=>{a&&i.startStreaming(a)})),b(D(()=>i.isComplete(),a=>{var n;a&&((n=e.onComplete)==null||n.call(e))}));const S=()=>`
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-segment {
display: inline-block;
opacity: 0;
animation: fadeIn ${e.fadeDuration??Math.round(1e3/Math.sqrt(Math.min(100,Math.max(1,f()))))}ms ease-out forwards;
}
.fade-segment-space {
white-space: pre;
}
`,u=()=>{if(typeof e.segmentDelay=="number")return Math.max(0,e.segmentDelay);const a=Math.min(100,Math.max(1,f()));return Math.max(1,Math.round(100/Math.sqrt(a)))};return(()=>{var a=R();return v(a,C(H,{get when(){return y()==="fade"},get fallback(){return G(()=>i.displayedText())},get children(){return[(()=>{var n=N();return v(n,S),n})(),(()=>{var n=P();return v(n,C(E,{get each(){return i.segments()},children:(s,d)=>{const m=()=>/^\s+$/.test(s.text);return(()=>{var o=W();return v(o,()=>s.text),I(r=>{var l=K("fade-segment",m()&&"fade-segment-space"),p=`${d()*u()}ms`;return l!==r.e&&z(o,r.e=l),p!==r.t&&F(o,"animation-delay",r.t=p),r},{e:void 0,t:void 0}),o})()}})),n})()]}})),I(()=>z(a,e.class)),a})()}J("kai-response-stream",{text:"",mode:"typewriter",speed:20,as:void 0},(t,{dispatch:e})=>C(_,{get textStream(){return t.text??""},get mode(){return t.mode},get speed(){return t.speed},get as(){return t.as},class:"text-body",onComplete:()=>e("kai-complete")}));