flow_ui 0.1.0 copy "flow_ui: ^0.1.0" to clipboard
flow_ui: ^0.1.0 copied to clipboard

Flow UI is an open-source Flutter UI library to build production-grade Chat & AI assistant interfaces.

example/lib/main.dart

import 'dart:async';

import 'package:flow_ui/flow_ui.dart';
import 'package:flutter/material.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flow_ui example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(extensions: [FlowTheme.light()]),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        extensions: [FlowTheme.dark()],
      ),
      home: const ChatPage(),
    );
  }
}

/// A complete chat surface: zero state with greeting and starters, a
/// thread that streams a canned reply, and a composer with menus.
///
/// flow_ui renders state and reports intent — there is no model behind
/// this page. Replace [_reply] with chunks from your backend.
class ChatPage extends StatefulWidget {
  const ChatPage({super.key});

  @override
  State<ChatPage> createState() => _ChatPageState();
}

const String _reply =
    'I can assist you with most tasks across this app — drafting an essay, '
    'putting together a briefing, or sketching out a new venture. What else '
    'can I do for you today?';

class _ChatPageState extends State<ChatPage> {
  final ScrollController _scroll = ScrollController();
  final TextEditingController _input = TextEditingController();
  List<FlowMessageData> _messages = const [];
  bool _generating = false;
  String _modelId = 'smart';
  Timer? _timer;
  int _nextId = 0;

  @override
  void dispose() {
    _timer?.cancel();
    _input.dispose();
    _scroll.dispose();
    super.dispose();
  }

  /// Appends the user turn plus a pending reply, then streams the canned
  /// text word by word — rebuild with [FlowMessageData.copyWith] as chunks
  /// arrive and the thread animates the reveal.
  void _send(String text) {
    _timer?.cancel();
    final id = 'msg${_nextId++}';
    setState(() {
      _messages = [
        ..._messages,
        FlowMessageData.text(id: id, role: FlowMessageRole.user, text: text),
        FlowMessageData(
          id: '$id-reply',
          role: FlowMessageRole.assistant,
          status: FlowMessageStatus.pending,
        ),
      ];
      _generating = true;
    });

    // A thinking beat, then the reply streams in.
    _timer = Timer(const Duration(milliseconds: 1200), () {
      final words = _reply.split(' ');
      var index = 0;
      _timer = Timer.periodic(const Duration(milliseconds: 80), (timer) {
        if (index >= words.length) {
          timer.cancel();
          _finish();
          return;
        }
        index++;
        setState(() {
          _messages = [
            ..._messages.sublist(0, _messages.length - 1),
            _messages.last.copyWith(
              parts: [FlowTextPart(words.take(index).join(' '))],
              status: FlowMessageStatus.streaming,
            ),
          ];
        });
      });
    });
  }

  void _finish() {
    _timer?.cancel();
    setState(() {
      _messages = [
        ..._messages.sublist(0, _messages.length - 1),
        _messages.last.copyWith(status: FlowMessageStatus.complete),
      ];
      _generating = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: context.flowColors.surface,
      body: FlowChatScreen(
        empty: _messages.isEmpty,
        greeting: const FlowGreeting(
          icon: Icons.wb_twilight,
          text: 'Good afternoon',
        ),
        suggestions: FlowSuggestionGroup(
          layout: FlowSuggestionLayout.column,
          suggestions: [
            for (final (icon, prompt) in const [
              (Icons.edit_note, 'Write an essay about life and enjoyment'),
              (Icons.event_available, 'Create a Monday briefing from my tasks'),
              (Icons.search, 'Suggest a new venture for me'),
            ])
              FlowSuggestion(
                label: prompt,
                icon: icon,
                onTap: () => _send(prompt),
              ),
          ],
        ),
        thread: FlowThread(
          messages: _messages,
          controller: _scroll,
          thinkingLabel: 'Thinking…',
        ),
        threadController: _scroll,
        jumpToLatestTooltip: 'Jump to latest',
        composer: FlowComposer(
          controller: _input,
          placeholder: 'How can I help you today?',
          isStreaming: _generating,
          onSend: _send,
          onStop: _finish,
          leadingActions: [
            FlowMenu(
              icon: Icons.add,
              tooltip: 'Add to chat',
              sheetTitle: 'Add to chat',
              entries: const [
                FlowMenuOption(
                  id: 'files',
                  icon: Icons.attach_file,
                  label: 'Add files or photos',
                ),
                FlowMenuDivider(),
                FlowMenuOption(
                  id: 'web',
                  icon: Icons.public,
                  label: 'Web search',
                ),
              ],
              onSelected: (_) {},
            ),
          ],
          trailingActions: [
            FlowModelSelector(
              tooltip: 'Choose model',
              sheetTitle: 'Select model',
              models: const [
                FlowModelOption(
                  id: 'fast',
                  label: 'Fast',
                  description: 'Quick answers',
                ),
                FlowModelOption(
                  id: 'smart',
                  label: 'Smart',
                  description: 'For hard problems',
                ),
              ],
              selectedId: _modelId,
              onSelected: (id) => setState(() => _modelId = id),
            ),
          ],
        ),
      ),
    );
  }
}
4
likes
160
points
79
downloads

Documentation

Documentation
API reference

Publisher

verified publisherstac.dev

Weekly Downloads

Flow UI is an open-source Flutter UI library to build production-grade Chat & AI assistant interfaces.

Homepage
Repository (GitHub)
View/report issues

Topics

#ai #chat #chatbot #assistant #ui

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flow_ui