@mathewk21/ai-chat-form
v0.2.26
Published
Schema-driven conversational AI chat form widget for React.
Readme
@mathewk21/ai-chat-form
Schema-driven conversational AI form widget for React — field-by-field chat flows with premium welcome and completion screens.
Install
npm install @mathewk21/ai-chat-form framer-motionImport styles once in your app entry (Tailwind/PostCSS must process screens.css):
import "@mathewk21/ai-chat-form";Configure PostCSS with the package Tailwind config:
// postcss.config.cjs
module.exports = {
plugins: {
tailwindcss: { config: "./node_modules/@mathewk21/ai-chat-form/tailwind.config.cjs" },
autoprefixer: {}
}
};Quick start
import { AIChatForm, createChatForm } from "@mathewk21/ai-chat-form";
const form = createChatForm({
id: "signup",
title: "Sign up",
fields: [
{ id: "name", type: "text", label: "What's your name?", required: true },
{ id: "email", type: "email", label: "Email?", required: true }
]
});
export function SignupFlow() {
return (
<AIChatForm
form={form}
theme="minimal"
onComplete={(result) => console.log(result.values)}
/>
);
}Welcome Screen
Show a cinematic onboarding screen before the conversation starts.
Schema configuration
const schema = {
id: "onboarding",
title: "Acme AI",
welcomeScreen: {
title: "Welcome to Acme AI Assistant",
subtitle: "Let's get your setup completed",
description: "This AI assistant will guide you through a few quick questions.",
logo: "/logo.png",
estimatedTime: "2 minutes",
layout: "centered", // centered | split | fullscreen
animation: "stagger", // fade | slide | stagger | none
progressPreview: true,
features: [
{ icon: "✦", title: "AI-guided", description: "Natural conversation" }
],
trustIndicators: ["SOC 2 aligned", "GDPR friendly"],
privacyNotice: "Your data is encrypted and never sold.",
primaryAction: { label: "Get Started" },
secondaryAction: { label: "Learn more", href: "https://acme.ai", variant: "ghost" }
},
fields: [/* ... */]
};Standalone widget
import { WelcomeScreen } from "@mathewk21/ai-chat-form";
<WelcomeScreen
title="Welcome to Acme AI Assistant"
subtitle="Let's get your setup completed"
description="This AI assistant will guide you through a few quick questions."
logo="/logo.png"
estimatedTime="2 minutes"
primaryAction={{ label: "Get Started", onClick: startFlow }}
/>Props override on AIChatForm
<AIChatForm
form={form}
welcomeScreen={{ estimatedTime: "3 minutes", themeColor: "#6366f1" }}
onAnalytics={(event) => analytics.track(event.type, event)}
/>Completion Screen
Celebrate submission with a polished thank-you experience.
Schema configuration
completionScreen: {
title: "You're all set!",
description: "Thanks for completing the setup.",
confetti: true,
animation: "celebrate",
nextSteps: [
{ label: "Explore dashboard", done: true },
{ label: "Invite your team" }
],
primaryAction: { label: "Visit Website", href: "https://acme.ai" },
secondaryAction: { label: "Start Again", variant: "secondary" },
emailConfirmationNotice: "Check your inbox for a confirmation email."
}Standalone widget
import { CompletionScreen } from "@mathewk21/ai-chat-form";
<CompletionScreen
title="You're all set!"
description="Thanks for completing the setup."
logo="/logo.png"
websiteUrl="https://acme.ai"
primaryAction={{ label: "Visit Website", href: "https://acme.ai" }}
secondaryAction={{ label: "Start Again", onClick: restartFlow }}
confetti
/>Customization
Custom renderers
<AIChatForm
form={form}
renderWelcomeScreen={(props) => <MyWelcome {...props} />}
renderCompletionScreen={(props) => <MyCompletion {...props} />}
/>Register screen widgets
import { registerScreenWidget, WelcomeScreen } from "@mathewk21/ai-chat-form";
registerScreenWidget("welcome", MyBrandedWelcome);
// Falls back to built-in WelcomeScreen if not registeredSlots
<WelcomeScreen
{...config}
slots={{
footer: <p>Need help? [email protected]</p>,
beforeCta: <TrustBadge />
}}
/>Theme inheritance
Screens inherit --acf-* tokens from the active AIChatForm theme (minimal, glass, dark, neon, enterprise). Override accent per screen:
welcomeScreen={{ themeColor: "#0ea5e9" }}Dark mode
Use theme="dark" on AIChatForm — welcome and completion screens automatically adapt via CSS variables.
Analytics hooks
onAnalytics={(event) => {
switch (event.type) {
case "welcome_view":
case "welcome_primary_click":
case "completion_view":
case "completion_restart":
// track event
break;
}
}}Multi-step welcome slides
welcomeScreen: {
title: "Welcome",
slides: [
{ title: "Meet your AI", description: "Personalized guidance" },
{ title: "Stay secure", description: "Enterprise-grade privacy" },
{ title: "Ready?", description: "Let's begin" }
],
primaryAction: { label: "Get Started" }
}AI Generated Follow-Ups
Add adaptive questions that are generated from prior answers, form metadata, and developer instructions.
Full working example: packages/demo/src/pages/aiChatForms/aiFollowUpFullShowcaseForm.ts — welcome screen, static fields, recursive LLM follow-ups, ranked options, conditional follow-up, completion screen. In the demo app, pick ★ Full AI Follow-Up Showcase.
Schema field
{
id: "ai_admissions",
type: "ai_generated_follow_up",
label: "Personalized follow-up",
followUp: {
ai: {
instructions: "Focus on university admissions. Keep questions short and friendly.",
domainContext: "Study abroad counseling",
temperature: 0.6,
allowedInputTypes: ["multiselect", "select", "textarea", "date"]
},
inputMode: "auto", // or "manual" + forcedInputType
flow: { mode: "recursive", maxFollowUps: 2 },
options: {
mode: "ai_ranked_static",
maxVisible: 5,
options: [{ label: "Australia" }, { label: "Canada" }, { label: "UK" }]
},
memory: { includePriorAnswers: true, includeConversation: true },
safety: { minConfidence: 0.7, fallbackQuestion: "What else should we know?" }
}
}LLM via marketplace execute API (chatbot SDK)
When VITE_DEMO_API_KEY (or executeApiKey) is set, follow-ups call the same /api/v1/execute/{model}/ endpoint as @mathewk21/chatbot, with heuristic fallback on failure.
import { createChatForm } from "@mathewk21/ai-chat-form";
const form = createChatForm(schema, {
followUp: {
executeApiKey: process.env.VITE_DEMO_API_KEY,
modelId: "deepseek-v32-non-thinking-mode",
externalEmail: "[email protected]"
}
});Model selection
Form-level default (all follow-up fields):
followUp: { modelId: "gpt-4o" }Per-field override:
{
type: "ai_generated_follow_up",
followUp: {
ai: { modelId: "claude-3-5-sonnet", instructions: "…" }
}
}Load models from the gateway catalog (same as chatbot):
import { AIFollowUpModelSelect, fetchFollowUpLlmModels } from "@mathewk21/ai-chat-form";
const models = await fetchFollowUpLlmModels({ apiKey: process.env.VITE_DEMO_API_KEY });
<AIFollowUpModelSelect
value={modelId}
onChange={setModelId}
executeApiKey={apiKey}
models={models}
/>Custom orchestration
import {
createChatForm,
createExecuteFollowUpProvider,
heuristicFollowUpProvider
} from "@mathewk21/ai-chat-form";
const form = createChatForm(schema, {
followUp: {
orchestrator: {
provider: createExecuteFollowUpProvider({ apiKey: "aom_live_…" }),
fallbackProvider: heuristicFollowUpProvider,
cache: true,
maxRetries: 1
},
sessionMetadata: { plan: "pro" },
userProfile: { locale: "en-AU" }
}
});Generated response shape
{
id: "fu_abc123",
generated_question: "Which countries are you most interested in studying in?",
generated_input_type: "multiselect",
resolved_field_type: "multiselect",
suggested_options: [{ label: "Australia" }, { label: "Canada" }],
ai_reasoning_metadata: {
based_on_answers: ["study_level"],
confidence: 0.92,
ranking_method: "semantic_similarity",
provider: "heuristic"
},
round: 0,
createdAt: "2026-05-27T12:00:00.000Z"
}Events
<AIChatForm
form={form}
onFollowUpGenerated={({ fieldId, snapshot }) => {
console.log(fieldId, snapshot.ai_reasoning_metadata);
}}
/>Demo templates: University Admissions, Recruitment, Lead Qualification, Healthcare Intake, Sales Discovery, and Smart Onboarding (see packages/demo).
Loading & Thinking UI Presets
Configure how the assistant appears while thinking, validating, generating follow-ups, and more.
import { AIChatForm, createChatForm } from "@mathewk21/ai-chat-form";
const form = createChatForm({
id: "onboarding",
title: "Onboarding",
loadingPresence: {
preset: "premium_saas",
stateVariants: {
searching_options: {
display: "shape",
shape: { kind: "gradient_orb", animation: "shimmer" }
},
processing_upload: {
display: "avatar",
avatar: { animation: "pulse" },
text: { staticText: "Securing your upload…" }
}
}
},
fields: [/* … */]
});| Mode | Description |
|------|-------------|
| avatar | Avatar + pulse/glow/breathing + typing dots + status text |
| shape | Abstract shapes (circle, blob, hexagon, orb) with GPU-friendly CSS animations |
| media | GIF, SVG, or MP4 loop for branded mascots |
Built-in presets: minimal, corporate, futuristic, friendly_assistant, glass_ai, neon, calm, playful, premium_saas, cyberpunk, robot_assistant (bundled GIF avatar while thinking; default out of the box).
Use AIChatLoadingPresenceBuilder for a visual editor with live preview and saved custom presets (localStorage).
API reference
| Export | Description |
|--------|-------------|
| WelcomeScreen | Standalone welcome widget |
| CompletionScreen | Standalone completion widget |
| registerScreenWidget | Replace built-in screen widgets |
| getScreenWidget | Resolve registered screen component |
| AIChatWelcomeScreenConfig | Welcome screen schema type |
| AIChatCompletionScreenConfig | Completion screen schema type |
| AIChatLoadingPresence | Standalone loading/thinking indicator |
| AIChatLoadingPresenceBuilder | Visual preset editor |
| AI_CHAT_LOADING_PRESETS | Built-in preset configs |
See TypeScript types for the full configuration surface (social links, calendar embed, submission recap, custom markdown, layouts, animations, and more).
