live_markdown_editor 0.2.0 copy "live_markdown_editor: ^0.2.0" to clipboard
live_markdown_editor: ^0.2.0 copied to clipboard

A source-preserving Flutter Markdown editor with raw, live, and read modes.

example/lib/main.dart

import 'package:flutter/widgets.dart';
import 'package:live_markdown_editor/live_markdown_editor.dart';

import 'cupertino_tab.dart';
import 'demo_settings.dart';
import 'foundation_tab.dart';
import 'material_tab.dart';

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

/// Three-tab demo host: a framework-neutral shell (widgets layer only) that
/// owns the shared controller, shared settings, and status line, and embeds
/// the editor in a Foundation (neutral), Material, and Cupertino tab.
final class EditorDemoApp extends StatefulWidget {
  const EditorDemoApp({super.key});

  @override
  State<EditorDemoApp> createState() => _EditorDemoAppState();
}

final class _EditorDemoAppState extends State<EditorDemoApp> {
  late final MarkdownEditorController _controller = MarkdownEditorController(
    text: sampleMarkdown,
  );
  DemoSettings _settings = const DemoSettings();
  var _tabIndex = 0;
  String _status = 'Edits stay in memory in this demo.';

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

  void _updateStatus(String message) => setState(() => _status = message);

  void _setMode(MarkdownEditorMode mode) =>
      setState(() => _controller.mode = mode);

  @override
  Widget build(BuildContext context) {
    final hostTheme = _settings.dark
        ? MarkdownEditorThemeData.dark()
        : MarkdownEditorThemeData.light();
    return WidgetsApp(
      color: hostTheme.backgroundColor,
      debugShowCheckedModeBanner: false,
      builder: (context, child) => ColoredBox(
        color: hostTheme.backgroundColor,
        child: SafeArea(
          child: Center(
            child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: demoContentMaxWidth),
              child: Column(
                children: [
                  _TabBar(
                    index: _tabIndex,
                    theme: hostTheme,
                    onSelect: _selectTab,
                  ),
                  Expanded(
                    child: switch (_tabIndex) {
                      0 => FoundationTab(
                        controller: _controller,
                        settings: _settings,
                        onSettingsChanged: (settings) =>
                            setState(() => _settings = settings),
                        onModeChanged: _setMode,
                        status: _status,
                        onStatus: _updateStatus,
                      ),
                      1 => MaterialConfigurationTab(
                        controller: _controller,
                        settings: _settings,
                        onSettingsChanged: (settings) =>
                            setState(() => _settings = settings),
                        onModeChanged: _setMode,
                        status: _status,
                        onStatus: _updateStatus,
                      ),
                      _ => CupertinoConfigurationTab(
                        controller: _controller,
                        settings: _settings,
                        onSettingsChanged: (settings) =>
                            setState(() => _settings = settings),
                        onModeChanged: _setMode,
                        status: _status,
                        onStatus: _updateStatus,
                      ),
                    },
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  void _selectTab(int index) => setState(() => _tabIndex = index);
}

final class _TabBar extends StatelessWidget {
  const _TabBar({
    required this.index,
    required this.theme,
    required this.onSelect,
  });

  final int index;
  final MarkdownEditorThemeData theme;
  final ValueChanged<int> onSelect;

  static const labels = ['foundation', 'material', 'cupertino'];

  @override
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: BoxDecoration(color: theme.codeBackgroundColor),
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            for (var i = 0; i < labels.length; i++)
              Semantics(
                button: true,
                selected: i == index,
                child: GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onTap: () => onSelect(i),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 14,
                      vertical: 10,
                    ),
                    child: Text(
                      labels[i],
                      style: theme.bodyStyle.copyWith(
                        color: i == index ? theme.accentColor : theme.textColor,
                        fontWeight: i == index
                            ? FontWeight.w700
                            : FontWeight.w400,
                      ),
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
3
likes
0
points
761
downloads

Publisher

unverified uploader

Weekly Downloads

A source-preserving Flutter Markdown editor with raw, live, and read modes.

Homepage
Repository (GitLab)
View/report issues

Topics

#markdown #editor #text-editor #flutter #widget

License

unknown (license)

Dependencies

flutter

More

Packages that depend on live_markdown_editor