@frankieai/react 0.1.4 → 0.1.5
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/dist/frankie.css +1 -1
- package/dist/index.cjs +86 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +87 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/chat/FrankieChatPage.tsx +75 -7
- package/src/hooks/useFrankieChat.ts +33 -15
- package/src/styles/frankie.css +161 -0
package/dist/frankie.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--radius-md:.375rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.frankie-root{--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.5rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.25rem;margin:0;padding-left:1.15rem;display:flex}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}}@layer utilities;@scope(.frankie-root){.visible{visibility:visible}.fixed{position:fixed}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-full{width:100%;height:100%}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[32rem\]{height:32rem}.h-full{height:100%}.h-px{height:1px}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-\[2\.25rem\]{min-height:2.25rem}.w-\[22rem\]{width:22rem}.w-full{width:100%}.max-w-\[8rem\]{max-width:8rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[14rem\]{max-width:14rem}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-\[calc\(var\(--frankie-radius\)\+4px\)\]{border-radius:calc(var(--frankie-radius) + 4px)}.rounded-\[calc\(var\(--frankie-radius\)-2px\)\]{border-radius:calc(var(--frankie-radius) - 2px)}.rounded-\[var\(--frankie-radius\)\]{border-radius:var(--frankie-radius)}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border{border-color:var(--frankie-border)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--frankie-background)}.bg-border{background-color:var(--frankie-border)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-muted{background-color:var(--frankie-muted)}.bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.bg-primary{background-color:var(--frankie-primary)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-secondary{background-color:var(--frankie-secondary)}.object-cover{object-fit:cover}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-emerald-600{color:var(--color-emerald-600)}.text-foreground{color:var(--frankie-foreground)}.text-muted-foreground{color:var(--frankie-muted-foreground)}.text-primary{color:var(--frankie-primary)}.text-primary-foreground{color:var(--frankie-primary-foreground)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--frankie-secondary-foreground)}.underline-offset-4{text-underline-offset:4px}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.hover\:border-border:hover{border-color:var(--frankie-border)}.hover\:bg-muted:hover{background-color:var(--frankie-muted)}.hover\:text-foreground:hover{color:var(--frankie-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}.hover\:opacity-100:hover{opacity:1}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-primary:focus-visible{--tw-ring-color:var(--frankie-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--radius-md:.375rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.frankie-root{--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.5rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.25rem;margin:0;padding-left:1.15rem;display:flex}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, var(--frankie-primary), transparent 65%), var(--frankie-background);flex-direction:column;min-width:0;display:flex;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, color-mix(in srgb, var(--frankie-primary) 8%, transparent), transparent 65%), var(--frankie-background)}}.frankie-chat-page{color:var(--frankie-foreground)}.frankie-page-header{border-bottom:1px solid var(--frankie-border);background:var(--frankie-background);flex:0 0 56px;justify-content:space-between;align-items:center;gap:16px;min-height:56px;padding:0 24px;display:flex}@supports (color:color-mix(in lab, red, red)){.frankie-page-header{background:color-mix(in srgb, var(--frankie-background) 92%, transparent)}}.frankie-page-header{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.frankie-page-header>div{align-items:center;gap:10px;display:flex}.frankie-page-header strong{font-size:.925rem;font-weight:650}.frankie-page-status{background:var(--frankie-primary);width:10px;height:10px;box-shadow:0 0 0 4px var(--frankie-primary);border-radius:999px}@supports (color:color-mix(in lab, red, red)){.frankie-page-status{box-shadow:0 0 0 4px color-mix(in srgb, var(--frankie-primary) 16%, transparent)}}.frankie-page-header button{border:1px solid var(--frankie-border);border-radius:calc(var(--frankie-radius) * .9);background:var(--frankie-secondary);cursor:pointer;min-height:36px;padding:0 13px}.frankie-page-header button:hover{border-color:var(--frankie-primary)}.frankie-page-canvas{flex:1;min-width:0;min-height:0;display:flex}.frankie-page-canvas>.frankie-inline{width:100%;max-width:56rem;margin:0 auto}.frankie-page-canvas .frankie-scroll{padding:2rem clamp(1rem,4vw,4rem) 1.25rem}.frankie-page-canvas .frankie-root>.border-t{background:linear-gradient(180deg, transparent, var(--frankie-background) 30%);border-top:0;padding:.75rem clamp(1rem,4vw,4rem) 1.5rem}.frankie-page-empty{text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:1rem;width:min(100%,38rem);min-height:100%;margin:auto;padding:clamp(2rem,7vh,4.5rem) 1rem 2rem;display:flex}.frankie-page-avatar{border-radius:calc(var(--frankie-radius) * 1.4);background:var(--frankie-primary);width:48px;height:48px;color:var(--frankie-primary-foreground);place-items:center;font-weight:750;display:grid}.frankie-page-kicker{color:var(--frankie-primary);letter-spacing:.1em;text-transform:uppercase;margin:0 0 .4rem;font-size:.7rem;font-weight:750}.frankie-page-empty h1{letter-spacing:-.045em;margin:0;font-size:clamp(1.65rem,4vw,2.15rem);line-height:1.08}.frankie-page-empty h1+p{max-width:30rem;color:var(--frankie-muted-foreground);margin:.6rem auto 0}.frankie-page-prompts{gap:.55rem;width:100%;margin-top:.4rem;display:grid}.frankie-page-prompts button{border:1px solid var(--frankie-border);border-radius:calc(var(--frankie-radius) * 1.25);background:var(--frankie-secondary);text-align:left;cursor:pointer;grid-template-columns:2rem minmax(0,1fr) auto;align-items:center;gap:.65rem;min-height:60px;padding:.75rem .9rem;display:grid}.frankie-page-prompts button:hover{border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-page-prompts button:hover{border-color:color-mix(in srgb, var(--frankie-primary) 58%, var(--frankie-border))}}.frankie-page-prompts button:hover{transform:translateY(-1px)}.frankie-page-prompts button>span{color:var(--frankie-muted-foreground);font-size:.68rem;font-weight:700}.frankie-page-prompts button>strong{font-size:.875rem}.frankie-page-prompts button>b{color:var(--frankie-primary);font-size:1rem}@media (max-width:640px){.frankie-page-header{flex-basis:52px;min-height:52px;padding:0 12px}.frankie-page-canvas .frankie-scroll{padding:1.25rem .75rem .5rem}.frankie-page-canvas .frankie-root>.border-t{padding:.65rem .75rem calc(.65rem + env(safe-area-inset-bottom))}}}@layer utilities;@scope(.frankie-root){.visible{visibility:visible}.fixed{position:fixed}.isolate{isolation:isolate}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-full{width:100%;height:100%}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[32rem\]{height:32rem}.h-full{height:100%}.h-px{height:1px}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-\[2\.25rem\]{min-height:2.25rem}.w-\[22rem\]{width:22rem}.w-full{width:100%}.max-w-\[8rem\]{max-width:8rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[14rem\]{max-width:14rem}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-\[calc\(var\(--frankie-radius\)\+4px\)\]{border-radius:calc(var(--frankie-radius) + 4px)}.rounded-\[calc\(var\(--frankie-radius\)-2px\)\]{border-radius:calc(var(--frankie-radius) - 2px)}.rounded-\[var\(--frankie-radius\)\]{border-radius:var(--frankie-radius)}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border{border-color:var(--frankie-border)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--frankie-background)}.bg-border{background-color:var(--frankie-border)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-muted{background-color:var(--frankie-muted)}.bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.bg-primary{background-color:var(--frankie-primary)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-secondary{background-color:var(--frankie-secondary)}.object-cover{object-fit:cover}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-emerald-600{color:var(--color-emerald-600)}.text-foreground{color:var(--frankie-foreground)}.text-muted-foreground{color:var(--frankie-muted-foreground)}.text-primary{color:var(--frankie-primary)}.text-primary-foreground{color:var(--frankie-primary-foreground)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--frankie-secondary-foreground)}.underline-offset-4{text-underline-offset:4px}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.hover\:border-border:hover{border-color:var(--frankie-border)}.hover\:bg-muted:hover{background-color:var(--frankie-muted)}.hover\:text-foreground:hover{color:var(--frankie-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}.hover\:opacity-100:hover{opacity:1}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-primary:focus-visible{--tw-ring-color:var(--frankie-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
package/dist/index.cjs
CHANGED
|
@@ -416,6 +416,7 @@ function useFrankieChat() {
|
|
|
416
416
|
const [restored, setRestored] = (0, import_react2.useState)(false);
|
|
417
417
|
const abortRef = (0, import_react2.useRef)(null);
|
|
418
418
|
const mounted = (0, import_react2.useRef)(true);
|
|
419
|
+
const messagesRef = (0, import_react2.useRef)([]);
|
|
419
420
|
(0, import_react2.useEffect)(() => {
|
|
420
421
|
mounted.current = true;
|
|
421
422
|
return () => {
|
|
@@ -431,13 +432,20 @@ function useFrankieChat() {
|
|
|
431
432
|
try {
|
|
432
433
|
const raw = window.localStorage.getItem(storageKey);
|
|
433
434
|
const stored = raw ? JSON.parse(raw) : [];
|
|
434
|
-
if (Array.isArray(stored) && stored.length && active)
|
|
435
|
+
if (Array.isArray(stored) && stored.length && active) {
|
|
436
|
+
messagesRef.current = stored;
|
|
437
|
+
setMessages(stored);
|
|
438
|
+
}
|
|
435
439
|
} catch {
|
|
436
440
|
}
|
|
437
441
|
}
|
|
438
442
|
try {
|
|
439
443
|
const remote = await client.resumeConversation();
|
|
440
|
-
if (active && remote?.messages.length)
|
|
444
|
+
if (active && remote?.messages.length) {
|
|
445
|
+
const restoredMessages = remote.messages;
|
|
446
|
+
messagesRef.current = restoredMessages;
|
|
447
|
+
setMessages(restoredMessages);
|
|
448
|
+
}
|
|
441
449
|
} catch {
|
|
442
450
|
} finally {
|
|
443
451
|
if (active) setRestored(true);
|
|
@@ -458,11 +466,11 @@ function useFrankieChat() {
|
|
|
458
466
|
if (messages.length) void client.syncConversation(messages, conversationTitle(messages)).catch(() => void 0);
|
|
459
467
|
}, [messages, busy, client, storageKey, restored]);
|
|
460
468
|
const patchAssistant = (0, import_react2.useCallback)((id, update) => {
|
|
461
|
-
|
|
462
|
-
(
|
|
463
|
-
(message) => message.id === id && message.role === "assistant" ? update(message) : message
|
|
464
|
-
)
|
|
469
|
+
const next = messagesRef.current.map(
|
|
470
|
+
(message) => message.id === id && message.role === "assistant" ? update(message) : message
|
|
465
471
|
);
|
|
472
|
+
messagesRef.current = next;
|
|
473
|
+
setMessages(next);
|
|
466
474
|
}, []);
|
|
467
475
|
const send = (0, import_react2.useCallback)(
|
|
468
476
|
async (text, opts) => {
|
|
@@ -473,15 +481,17 @@ function useFrankieChat() {
|
|
|
473
481
|
const assistantId = nextId("a");
|
|
474
482
|
setError(void 0);
|
|
475
483
|
setBusy(true);
|
|
476
|
-
|
|
477
|
-
...current,
|
|
484
|
+
const next = [
|
|
485
|
+
...messagesRef.current,
|
|
478
486
|
newUserMessage(
|
|
479
487
|
nextId("u"),
|
|
480
488
|
trimmed,
|
|
481
489
|
attachments.map((file) => ({ name: file.name, mimeType: file.mimeType }))
|
|
482
490
|
),
|
|
483
491
|
newAssistantMessage(assistantId)
|
|
484
|
-
]
|
|
492
|
+
];
|
|
493
|
+
messagesRef.current = next;
|
|
494
|
+
setMessages(next);
|
|
485
495
|
const abort = new AbortController();
|
|
486
496
|
abortRef.current = abort;
|
|
487
497
|
try {
|
|
@@ -522,13 +532,15 @@ function useFrankieChat() {
|
|
|
522
532
|
patchAssistant(assistantId, (current) => ({ ...current, status: "error", error: message }));
|
|
523
533
|
}
|
|
524
534
|
} finally {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
535
|
+
patchAssistant(
|
|
536
|
+
assistantId,
|
|
537
|
+
(message) => message.status === "streaming" ? { ...message, status: "done" } : message
|
|
538
|
+
);
|
|
539
|
+
const transcript = messagesRef.current;
|
|
540
|
+
if (transcript.length) {
|
|
541
|
+
await client.syncConversation(transcript, conversationTitle(transcript)).catch(() => void 0);
|
|
531
542
|
}
|
|
543
|
+
if (mounted.current) setBusy(false);
|
|
532
544
|
abortRef.current = null;
|
|
533
545
|
}
|
|
534
546
|
},
|
|
@@ -538,6 +550,7 @@ function useFrankieChat() {
|
|
|
538
550
|
const reset = (0, import_react2.useCallback)(() => {
|
|
539
551
|
abortRef.current?.abort();
|
|
540
552
|
client.resetSession();
|
|
553
|
+
messagesRef.current = [];
|
|
541
554
|
setMessages([]);
|
|
542
555
|
setError(void 0);
|
|
543
556
|
setBusy(false);
|
|
@@ -1307,6 +1320,62 @@ function FrankieInline({ className, style, ...panelProps }) {
|
|
|
1307
1320
|
|
|
1308
1321
|
// src/components/chat/FrankieChatPage.tsx
|
|
1309
1322
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1323
|
+
function PageEmptyState() {
|
|
1324
|
+
const { config } = useFrankie();
|
|
1325
|
+
const { send, busy } = useFrankieChat();
|
|
1326
|
+
const name = config?.branding.name ?? "Frankie";
|
|
1327
|
+
const prompts = config?.suggestedPrompts?.slice(0, 3) ?? [];
|
|
1328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "frankie-page-empty", "aria-label": "Start a conversation", children: [
|
|
1329
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "frankie-page-avatar", "aria-hidden": true, children: name.trim().slice(0, 1).toUpperCase() }),
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
1331
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "frankie-page-kicker", children: [
|
|
1332
|
+
name,
|
|
1333
|
+
" assistant"
|
|
1334
|
+
] }),
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h1", { children: "What would you like to do?" }),
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: config?.greeting ?? "Ask a question or choose a task to get started." })
|
|
1337
|
+
] }),
|
|
1338
|
+
prompts.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "frankie-page-prompts", children: prompts.map((prompt, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("button", { type: "button", disabled: busy, onClick: () => send(prompt), children: [
|
|
1339
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: String(index + 1).padStart(2, "0") }),
|
|
1340
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: prompt }),
|
|
1341
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("b", { "aria-hidden": true, children: "\u2197" })
|
|
1342
|
+
] }, prompt)) }) : null
|
|
1343
|
+
] });
|
|
1344
|
+
}
|
|
1345
|
+
function PageChrome({
|
|
1346
|
+
header,
|
|
1347
|
+
footer,
|
|
1348
|
+
emptyState,
|
|
1349
|
+
renderMessage,
|
|
1350
|
+
renderTool,
|
|
1351
|
+
placeholder,
|
|
1352
|
+
autoFocus
|
|
1353
|
+
}) {
|
|
1354
|
+
const { config } = useFrankie();
|
|
1355
|
+
const { reset } = useFrankieChat();
|
|
1356
|
+
const name = config?.branding.name ?? "Frankie";
|
|
1357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1358
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("header", { className: "frankie-page-header", children: [
|
|
1359
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
1360
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "frankie-page-status", "aria-hidden": true }),
|
|
1361
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: name })
|
|
1362
|
+
] }),
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: reset, "aria-label": "Start a new conversation", children: "New chat" })
|
|
1364
|
+
] }),
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "frankie-page-canvas", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1366
|
+
FrankieInline,
|
|
1367
|
+
{
|
|
1368
|
+
header: header ?? false,
|
|
1369
|
+
footer,
|
|
1370
|
+
emptyState: emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PageEmptyState, {}),
|
|
1371
|
+
renderMessage,
|
|
1372
|
+
renderTool,
|
|
1373
|
+
placeholder,
|
|
1374
|
+
autoFocus
|
|
1375
|
+
}
|
|
1376
|
+
) })
|
|
1377
|
+
] });
|
|
1378
|
+
}
|
|
1310
1379
|
function FrankieChatPage({
|
|
1311
1380
|
className,
|
|
1312
1381
|
style,
|
|
@@ -1322,10 +1391,10 @@ function FrankieChatPage({
|
|
|
1322
1391
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1323
1392
|
"main",
|
|
1324
1393
|
{
|
|
1325
|
-
className,
|
|
1394
|
+
className: ["frankie-root", "frankie-chat-page", className].filter(Boolean).join(" "),
|
|
1326
1395
|
style: { height: "100dvh", minHeight: "100dvh", width: "100%", ...style },
|
|
1327
1396
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FrankieProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1328
|
-
|
|
1397
|
+
PageChrome,
|
|
1329
1398
|
{
|
|
1330
1399
|
header,
|
|
1331
1400
|
footer,
|