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

A WYSIWYG Markdown editor widget for Flutter. Type Markdown and see live-rendered bold, italic, headings, and more — without ever seeing raw syntax markers. Includes a customizable controller and toolbar.

example/lib/main.dart

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

void main() {
  runApp(const MarkdownLiveExampleApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Markdown Live Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF4A90D9)),
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF6CB4FF),
          brightness: Brightness.dark,
        ),
        useMaterial3: true,
      ),
      home: const EditorPage(),
    );
  }
}

class EditorPage extends StatefulWidget {
  const EditorPage({super.key});

  @override
  State<EditorPage> createState() => _EditorPageState();
}

class _EditorPageState extends State<EditorPage> {
  late final MarkdownLiveController _controller;
  bool _showRawMarkdown = false;

  @override
  void initState() {
    super.initState();
    _controller = MarkdownLiveController(
      text: _sampleMarkdown,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final theme = isDark ? MarkdownLiveTheme.dark() : MarkdownLiveTheme.light();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Markdown Live'),
        actions: [
          // Toggle raw Markdown view
          IconButton(
            icon: Icon(_showRawMarkdown ? Icons.visibility : Icons.visibility_off),
            tooltip: _showRawMarkdown ? 'Show rendered' : 'Show raw Markdown',
            onPressed: () {
              setState(() {
                _showRawMarkdown = !_showRawMarkdown;
              });
            },
          ),
        ],
      ),
      body: Column(
        children: [
          // Toolbar
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
            child: MarkdownLiveToolbar(
              controller: _controller,
              onLinkAction: (controller) {
                _showLinkDialog(context, controller);
              },
            ),
          ),

          const Divider(height: 1),

          // Editor
          Expanded(
            child: _showRawMarkdown
                ? _buildRawView()
                : MarkdownLiveEditor(
                    controller: _controller,
                    theme: theme,
                    autofocus: true,
                    maxLines: null,
                    onChanged: (value) {
                      // You can access the raw Markdown here:
                      // print(value);
                    },
                  ),
          ),
        ],
      ),
    );
  }

  Widget _buildRawView() {
    return Padding(
      padding: const EdgeInsets.all(16),
      child: ListenableBuilder(
        listenable: _controller,
        builder: (context, _) {
          return SelectableText(
            _controller.text,
            style: const TextStyle(
              fontFamily: 'monospace',
              fontSize: 14,
            ),
          );
        },
      ),
    );
  }

  void _showLinkDialog(BuildContext context, MarkdownLiveController controller) {
    final textCtrl = TextEditingController();
    final urlCtrl = TextEditingController(text: 'https://');

    // Pre-fill with selected text if any
    if (controller.selection.isValid && !controller.selection.isCollapsed) {
      textCtrl.text = controller.selection.textInside(controller.text);
    }

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Insert Link'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: textCtrl,
              decoration: const InputDecoration(
                labelText: 'Link text',
                hintText: 'Display text',
              ),
            ),
            const SizedBox(height: 12),
            TextField(
              controller: urlCtrl,
              decoration: const InputDecoration(
                labelText: 'URL',
                hintText: 'https://example.com',
              ),
            ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Cancel'),
          ),
          FilledButton(
            onPressed: () {
              controller.insertLink(
                textCtrl.text.isEmpty ? 'link' : textCtrl.text,
                urlCtrl.text,
              );
              Navigator.pop(context);
            },
            child: const Text('Insert'),
          ),
        ],
      ),
    );
  }
}

const _sampleMarkdown = '''# Welcome to Markdown Live

This is a **WYSIWYG** Markdown editor for Flutter.

## Features

You can write **bold text**, _italic text_, and ***bold italic text***.

Use ~~strikethrough~~ for deleted content.

Add `inline code` for technical terms.

### Links

Visit [Flutter](https://flutter.dev) for more info.

#### Try It Out

Just start typing below this line and see the magic!
''';
3
likes
140
points
16
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A WYSIWYG Markdown editor widget for Flutter. Type Markdown and see live-rendered bold, italic, headings, and more — without ever seeing raw syntax markers. Includes a customizable controller and toolbar.

Repository (GitHub)
View/report issues

Topics

#markdown #editor #wysiwyg #rich-text #widget

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on markdown_live