markdown_live 0.1.0
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.
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!
''';