@frankieai/react 0.2.17 → 0.2.19
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 +280 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -4
- package/dist/index.d.ts +47 -4
- package/dist/index.js +241 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bottom-bars.test.tsx +67 -0
- package/src/components/chat/ChatEmptyState.tsx +1 -1
- package/src/components/chat/ChatPanel.tsx +2 -2
- package/src/components/chat/FrankieChatPage.tsx +17 -5
- package/src/components/chat/FrankieInline.tsx +4 -4
- package/src/components/chat/FrankieWidget.tsx +70 -7
- package/src/components/chat/MessageBubble.tsx +7 -5
- package/src/generated/css-content.ts +1 -1
- package/src/hooks/FrankieProvider.tsx +17 -3
- package/src/hooks/useFrankieChat.ts +59 -8
- package/src/index.ts +1 -1
- package/src/lib/bottom-bars.ts +43 -0
- package/src/lib/client.ts +21 -3
- package/src/lib/theme.ts +22 -1
- package/src/lib/viewport-fill.ts +39 -0
- package/src/styles/frankie.css +22 -3
- package/src/theme-ready.test.tsx +36 -0
- package/src/turn-follow.test.tsx +111 -0
package/dist/index.d.cts
CHANGED
|
@@ -92,9 +92,18 @@ declare class FrankieClient {
|
|
|
92
92
|
getConfig(signal?: AbortSignal): Promise<PublicWidgetConfig>;
|
|
93
93
|
ensureSession(context?: PageContext): Promise<CreateSessionResponse>;
|
|
94
94
|
listConversations(): Promise<ChatConversation[]>;
|
|
95
|
+
/** Whether a conversation can be reloaded from the server (a signed-in user and a conversation id). */
|
|
96
|
+
get canResume(): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Ask the server to stop the running turn. Closing the stream no longer
|
|
99
|
+
* stops it (a closed tab shouldn't lose the reply), so Stop says so
|
|
100
|
+
* explicitly. Best effort: the stream is closed right after either way.
|
|
101
|
+
*/
|
|
102
|
+
stopTurn(): Promise<void>;
|
|
95
103
|
resumeConversation(id?: string | undefined): Promise<{
|
|
96
104
|
messages: unknown[];
|
|
97
105
|
title: string;
|
|
106
|
+
busy: boolean;
|
|
98
107
|
} | undefined>;
|
|
99
108
|
syncConversation(messages: unknown[], title?: string): Promise<void>;
|
|
100
109
|
deleteConversation(id: string): Promise<void>;
|
|
@@ -144,6 +153,13 @@ interface FrankieContextValue {
|
|
|
144
153
|
injectStyles: boolean;
|
|
145
154
|
/** The host page's colors, sampled once for "inherit my site's theme" (null: not inheriting, or unreadable). */
|
|
146
155
|
hostTheme: Partial<WidgetTheme> | null;
|
|
156
|
+
/**
|
|
157
|
+
* True once the chat knows its colors: the config (or its error) has arrived
|
|
158
|
+
* and, when inheriting, the host page has been sampled. Until then the chat
|
|
159
|
+
* stays invisible, so a visitor in OS dark mode never sees a black flash on
|
|
160
|
+
* a light site before the real theme lands.
|
|
161
|
+
*/
|
|
162
|
+
themeReady: boolean;
|
|
147
163
|
}
|
|
148
164
|
declare function FrankieProvider({ children, context, theme, config: providedConfig, injectStyles, ...clientOptions }: FrankieProviderProps): react.JSX.Element;
|
|
149
165
|
declare function useFrankie(): FrankieContextValue;
|
|
@@ -249,6 +265,17 @@ interface FrankieWidgetProps extends ChatPanelProps {
|
|
|
249
265
|
toggle: () => void;
|
|
250
266
|
label: string;
|
|
251
267
|
}) => React.ReactNode;
|
|
268
|
+
/**
|
|
269
|
+
* `false` hides the floating button, for apps with their own entry point:
|
|
270
|
+
* give any element `data-frankie-open` (a nav tab, a "Help" link) and a
|
|
271
|
+
* click on it opens the chat. Defaults to `true`.
|
|
272
|
+
*/
|
|
273
|
+
launcher?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Sit above fixed bars along the bottom of the page (a mobile tab bar, a
|
|
276
|
+
* cookie banner) instead of underneath them. Defaults to `true`.
|
|
277
|
+
*/
|
|
278
|
+
avoidBottomBars?: boolean;
|
|
252
279
|
}
|
|
253
280
|
/**
|
|
254
281
|
* The drop-in embed: a floating launcher plus the chat panel.
|
|
@@ -256,7 +283,7 @@ interface FrankieWidgetProps extends ChatPanelProps {
|
|
|
256
283
|
* Renders `position: fixed` at the document level, so it does not care what
|
|
257
284
|
* layout the host page uses.
|
|
258
285
|
*/
|
|
259
|
-
declare function FrankieWidget({ position, offset, defaultOpen, zIndex, open: controlledOpen, onOpenChange, renderLauncher, ...panelProps }: FrankieWidgetProps): react.JSX.Element;
|
|
286
|
+
declare function FrankieWidget({ position, offset, defaultOpen, zIndex, open: controlledOpen, onOpenChange, renderLauncher, launcher, avoidBottomBars, ...panelProps }: FrankieWidgetProps): react.JSX.Element;
|
|
260
287
|
|
|
261
288
|
interface FrankieInlineProps extends ChatPanelProps {
|
|
262
289
|
/** Extra styles on the filling wrapper — e.g. a `maxWidth` to centre the column. */
|
|
@@ -280,9 +307,15 @@ interface FrankieChatPageProps extends Omit<FrankieProviderProps, "children">, P
|
|
|
280
307
|
showHistory?: boolean;
|
|
281
308
|
/** Optional host navigation, e.g. a Back to dashboard link. */
|
|
282
309
|
navigation?: React.ReactNode;
|
|
310
|
+
/**
|
|
311
|
+
* Grow to fill the screen from where the chat starts down to the bottom
|
|
312
|
+
* edge, or to the top of a fixed bottom bar. Defaults to true; set false
|
|
313
|
+
* when a sized parent should decide the height.
|
|
314
|
+
*/
|
|
315
|
+
fillViewport?: boolean;
|
|
283
316
|
}
|
|
284
317
|
/** Reusable product chat with one shared conversation state and scoped styling. */
|
|
285
|
-
declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, showHistory, navigation, ...provider }: FrankieChatPageProps): react.JSX.Element;
|
|
318
|
+
declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, showHistory, navigation, fillViewport, ...provider }: FrankieChatPageProps): react.JSX.Element;
|
|
286
319
|
|
|
287
320
|
interface ComposerAttachmentsConfig {
|
|
288
321
|
enabled: boolean;
|
|
@@ -340,7 +373,9 @@ declare function TypingDots(): react.JSX.Element;
|
|
|
340
373
|
* the first words, or during the pause after a tool result while the model
|
|
341
374
|
* composes its answer — so those gaps read as "loading" rather than frozen.
|
|
342
375
|
*/
|
|
343
|
-
declare function Thinking(
|
|
376
|
+
declare function Thinking({ delayed }: {
|
|
377
|
+
delayed?: boolean;
|
|
378
|
+
}): react.JSX.Element;
|
|
344
379
|
|
|
345
380
|
/**
|
|
346
381
|
* A deliberately small Markdown subset — headings, paragraphs, lists, fenced
|
|
@@ -467,8 +502,16 @@ declare function extractChoices(text: string): ExtractedChoices;
|
|
|
467
502
|
declare function themeToCssVars(theme: WidgetTheme | undefined): CSSProperties;
|
|
468
503
|
/** Resolve `mode: "system"` against the browser, so the widget can hard-set a class. */
|
|
469
504
|
declare function resolveMode(mode: WidgetTheme["mode"]): "light" | "dark";
|
|
505
|
+
/**
|
|
506
|
+
* `resolveMode` as a hook. Server-rendered pages can't know the visitor's
|
|
507
|
+
* scheme, and a hydrated attribute that differs from the server's is never
|
|
508
|
+
* patched, so a plain `resolveMode` call could leave "system" stuck on light.
|
|
509
|
+
* This renders light on the server and during hydration, then the visitor's
|
|
510
|
+
* scheme, and follows it when they switch.
|
|
511
|
+
*/
|
|
512
|
+
declare function useResolvedMode(mode: WidgetTheme["mode"]): "light" | "dark";
|
|
470
513
|
|
|
471
514
|
/** shadcn/ui's class helper: conditional classes with Tailwind conflict resolution. */
|
|
472
515
|
declare function cn(...inputs: ClassValue[]): string;
|
|
473
516
|
|
|
474
|
-
export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Choices, Composer, type ExtractedChoices, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, Thinking, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, extractChoices, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };
|
|
517
|
+
export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Choices, Composer, type ExtractedChoices, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, Thinking, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, extractChoices, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme, useResolvedMode };
|
package/dist/index.d.ts
CHANGED
|
@@ -92,9 +92,18 @@ declare class FrankieClient {
|
|
|
92
92
|
getConfig(signal?: AbortSignal): Promise<PublicWidgetConfig>;
|
|
93
93
|
ensureSession(context?: PageContext): Promise<CreateSessionResponse>;
|
|
94
94
|
listConversations(): Promise<ChatConversation[]>;
|
|
95
|
+
/** Whether a conversation can be reloaded from the server (a signed-in user and a conversation id). */
|
|
96
|
+
get canResume(): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Ask the server to stop the running turn. Closing the stream no longer
|
|
99
|
+
* stops it (a closed tab shouldn't lose the reply), so Stop says so
|
|
100
|
+
* explicitly. Best effort: the stream is closed right after either way.
|
|
101
|
+
*/
|
|
102
|
+
stopTurn(): Promise<void>;
|
|
95
103
|
resumeConversation(id?: string | undefined): Promise<{
|
|
96
104
|
messages: unknown[];
|
|
97
105
|
title: string;
|
|
106
|
+
busy: boolean;
|
|
98
107
|
} | undefined>;
|
|
99
108
|
syncConversation(messages: unknown[], title?: string): Promise<void>;
|
|
100
109
|
deleteConversation(id: string): Promise<void>;
|
|
@@ -144,6 +153,13 @@ interface FrankieContextValue {
|
|
|
144
153
|
injectStyles: boolean;
|
|
145
154
|
/** The host page's colors, sampled once for "inherit my site's theme" (null: not inheriting, or unreadable). */
|
|
146
155
|
hostTheme: Partial<WidgetTheme> | null;
|
|
156
|
+
/**
|
|
157
|
+
* True once the chat knows its colors: the config (or its error) has arrived
|
|
158
|
+
* and, when inheriting, the host page has been sampled. Until then the chat
|
|
159
|
+
* stays invisible, so a visitor in OS dark mode never sees a black flash on
|
|
160
|
+
* a light site before the real theme lands.
|
|
161
|
+
*/
|
|
162
|
+
themeReady: boolean;
|
|
147
163
|
}
|
|
148
164
|
declare function FrankieProvider({ children, context, theme, config: providedConfig, injectStyles, ...clientOptions }: FrankieProviderProps): react.JSX.Element;
|
|
149
165
|
declare function useFrankie(): FrankieContextValue;
|
|
@@ -249,6 +265,17 @@ interface FrankieWidgetProps extends ChatPanelProps {
|
|
|
249
265
|
toggle: () => void;
|
|
250
266
|
label: string;
|
|
251
267
|
}) => React.ReactNode;
|
|
268
|
+
/**
|
|
269
|
+
* `false` hides the floating button, for apps with their own entry point:
|
|
270
|
+
* give any element `data-frankie-open` (a nav tab, a "Help" link) and a
|
|
271
|
+
* click on it opens the chat. Defaults to `true`.
|
|
272
|
+
*/
|
|
273
|
+
launcher?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Sit above fixed bars along the bottom of the page (a mobile tab bar, a
|
|
276
|
+
* cookie banner) instead of underneath them. Defaults to `true`.
|
|
277
|
+
*/
|
|
278
|
+
avoidBottomBars?: boolean;
|
|
252
279
|
}
|
|
253
280
|
/**
|
|
254
281
|
* The drop-in embed: a floating launcher plus the chat panel.
|
|
@@ -256,7 +283,7 @@ interface FrankieWidgetProps extends ChatPanelProps {
|
|
|
256
283
|
* Renders `position: fixed` at the document level, so it does not care what
|
|
257
284
|
* layout the host page uses.
|
|
258
285
|
*/
|
|
259
|
-
declare function FrankieWidget({ position, offset, defaultOpen, zIndex, open: controlledOpen, onOpenChange, renderLauncher, ...panelProps }: FrankieWidgetProps): react.JSX.Element;
|
|
286
|
+
declare function FrankieWidget({ position, offset, defaultOpen, zIndex, open: controlledOpen, onOpenChange, renderLauncher, launcher, avoidBottomBars, ...panelProps }: FrankieWidgetProps): react.JSX.Element;
|
|
260
287
|
|
|
261
288
|
interface FrankieInlineProps extends ChatPanelProps {
|
|
262
289
|
/** Extra styles on the filling wrapper — e.g. a `maxWidth` to centre the column. */
|
|
@@ -280,9 +307,15 @@ interface FrankieChatPageProps extends Omit<FrankieProviderProps, "children">, P
|
|
|
280
307
|
showHistory?: boolean;
|
|
281
308
|
/** Optional host navigation, e.g. a Back to dashboard link. */
|
|
282
309
|
navigation?: React.ReactNode;
|
|
310
|
+
/**
|
|
311
|
+
* Grow to fill the screen from where the chat starts down to the bottom
|
|
312
|
+
* edge, or to the top of a fixed bottom bar. Defaults to true; set false
|
|
313
|
+
* when a sized parent should decide the height.
|
|
314
|
+
*/
|
|
315
|
+
fillViewport?: boolean;
|
|
283
316
|
}
|
|
284
317
|
/** Reusable product chat with one shared conversation state and scoped styling. */
|
|
285
|
-
declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, showHistory, navigation, ...provider }: FrankieChatPageProps): react.JSX.Element;
|
|
318
|
+
declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, showHistory, navigation, fillViewport, ...provider }: FrankieChatPageProps): react.JSX.Element;
|
|
286
319
|
|
|
287
320
|
interface ComposerAttachmentsConfig {
|
|
288
321
|
enabled: boolean;
|
|
@@ -340,7 +373,9 @@ declare function TypingDots(): react.JSX.Element;
|
|
|
340
373
|
* the first words, or during the pause after a tool result while the model
|
|
341
374
|
* composes its answer — so those gaps read as "loading" rather than frozen.
|
|
342
375
|
*/
|
|
343
|
-
declare function Thinking(
|
|
376
|
+
declare function Thinking({ delayed }: {
|
|
377
|
+
delayed?: boolean;
|
|
378
|
+
}): react.JSX.Element;
|
|
344
379
|
|
|
345
380
|
/**
|
|
346
381
|
* A deliberately small Markdown subset — headings, paragraphs, lists, fenced
|
|
@@ -467,8 +502,16 @@ declare function extractChoices(text: string): ExtractedChoices;
|
|
|
467
502
|
declare function themeToCssVars(theme: WidgetTheme | undefined): CSSProperties;
|
|
468
503
|
/** Resolve `mode: "system"` against the browser, so the widget can hard-set a class. */
|
|
469
504
|
declare function resolveMode(mode: WidgetTheme["mode"]): "light" | "dark";
|
|
505
|
+
/**
|
|
506
|
+
* `resolveMode` as a hook. Server-rendered pages can't know the visitor's
|
|
507
|
+
* scheme, and a hydrated attribute that differs from the server's is never
|
|
508
|
+
* patched, so a plain `resolveMode` call could leave "system" stuck on light.
|
|
509
|
+
* This renders light on the server and during hydration, then the visitor's
|
|
510
|
+
* scheme, and follows it when they switch.
|
|
511
|
+
*/
|
|
512
|
+
declare function useResolvedMode(mode: WidgetTheme["mode"]): "light" | "dark";
|
|
470
513
|
|
|
471
514
|
/** shadcn/ui's class helper: conditional classes with Tailwind conflict resolution. */
|
|
472
515
|
declare function cn(...inputs: ClassValue[]): string;
|
|
473
516
|
|
|
474
|
-
export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Choices, Composer, type ExtractedChoices, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, Thinking, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, extractChoices, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };
|
|
517
|
+
export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Choices, Composer, type ExtractedChoices, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, Thinking, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, extractChoices, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme, useResolvedMode };
|