flutter_ai_elements 0.1.12
flutter_ai_elements: ^0.1.12 copied to clipboard
Composable, themeable Flutter UI for AI chat — conversation, message bubbles, a streaming-aware composer, and a loader — styled entirely through a mobile-first AiThemeExtension. No shadcn/forui dependency.
flutter_ai_elements #
☕ Support this project #
If flutter_ai saves you time, buy me a coffee ☕ — it keeps the whole family maintained.

Composable, themeable Flutter UI for AI chat — the UI layer of the
flutter_ai family.
It adopts the Vercel AI Elements component vocabulary but renders through a
mobile-first AiThemeExtension, built from base Flutter widgets. No
shadcn_flutter / forui dependency, no hardcoded Material or Cupertino look —
restyle everything via theme tokens.
Widgets #
Presentational (plain data + callbacks; reusable, testable):
AiMessageBubble— renders one message's parts (text, reasoning, tool calls, results, files, sources, data), role-aware, with streaming-safe semantics.AiConversationView— a scrolling list of bubbles, optional thinking loader.AiComposer— the presentational input: a leading attach (+) button and a main button that is Live while empty, Send once you type, and Stop while streaming; emits haptics. Use this only if you're wiring callbacks yourself.AiLoader— a pulsing three-dot thinking indicator.
Controller-bound (wire to a UseChatController — what you usually want):
AiChat— live transcript with auto-scroll and a thinking loader.AiPromptInput— the drop-in composer: wrapsAiComposerand wires it tosendText/stop. Prefer this overAiComposer.
Quick start #
import 'package:flutter/material.dart';
import 'package:flutter_ai_elements/flutter_ai_elements.dart';
class ChatScreen extends StatelessWidget {
const ChatScreen({super.key, required this.controller});
final UseChatController controller; // from flutter_ai_client
@override
Widget build(BuildContext context) => Scaffold(
// Batteries-included: transcript + composer + layout in one widget.
body: AiChatView(controller: controller),
);
}
Need a custom layout between the transcript and composer? Compose the pieces yourself instead:
Scaffold(
body: Column(
children: [
Expanded(child: AiChat(controller: controller)),
AiPromptInput(controller: controller),
],
),
);
Theming #
Register an AiThemeExtension (or override the default) on your ThemeData:
MaterialApp(
theme: ThemeData(
extensions: [
AiThemeExtension.fallback().copyWith(
userBubbleColor: const Color(0xFF7C3AED),
bubbleRadius: const BorderRadius.all(Radius.circular(28)),
enableHaptics: true,
),
],
),
home: const ChatScreen(...),
);
Widgets read tokens via AiThemeExtension.of(context), falling back to the
mobile-first default when none is registered. All visual constants live behind
this one extension, so a future flutter_ai_design_system can extract them
without breaking the API.
Rich text #
Text renders through an injectable AiTextRenderer (TextRenderer<Widget>); the
default is PlainTextRenderer. Provide your own for Markdown, code highlighting,
or LaTeX:
AiChat(controller: controller, textRenderer: MyMarkdownRenderer());
Status #
Published on pub.dev (see the CHANGELOG); depends on the sibling flutter_ai
packages.
See example/ for a full app.
