flutter_monaco_editor 0.5.1
flutter_monaco_editor: ^0.5.1 copied to clipboard
A complete Flutter wrapper for Monaco Editor (VS Code's editor) with full API parity across Web, Android, iOS, macOS, Linux, and Windows.
import 'package:flutter/material.dart';
import 'package:flutter_monaco_editor/flutter_monaco_editor.dart';
import 'demos/demo.dart';
void main() {
runApp(const GalleryApp());
}
class GalleryApp extends StatelessWidget {
const GalleryApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'flutter_monaco_editor gallery',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorSchemeSeed: const Color(0xFF58A6FF),
),
home: const GalleryHome(),
);
}
}
class GalleryHome extends StatefulWidget {
const GalleryHome({super.key});
@override
State<GalleryHome> createState() => _GalleryHomeState();
}
class _GalleryHomeState extends State<GalleryHome> {
int _selected = 0;
@override
Widget build(BuildContext context) {
final demo = demos[_selected];
return Scaffold(
body: SafeArea(child: Row(
children: [
_SidebarRail(
selected: _selected,
onSelect: (i) => setState(() => _selected = i),
),
const VerticalDivider(width: 1),
Expanded(
child: KeyedSubtree(
key: ValueKey(_selected),
child: demo.builder(context),
),
),
],
)),
);
}
}
class _SidebarRail extends StatelessWidget {
const _SidebarRail({required this.selected, required this.onSelect});
final int selected;
final ValueChanged<int> onSelect;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SizedBox(
width: 260,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 6),
child: Row(
children: [
Container(
width: 28,
height: 28,
decoration: BoxDecoration(
color: theme.colorScheme.primary,
borderRadius: BorderRadius.circular(6),
),
alignment: Alignment.center,
child: const Icon(Icons.code, size: 18, color: Colors.white),
),
const SizedBox(width: 10),
Expanded(
child: Text(
'flutter_monaco_editor',
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 20, bottom: 12),
child: Text(
'Monaco $monacoVersion • gallery',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
),
const Divider(height: 1),
Expanded(
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 8),
itemCount: demos.length,
itemBuilder: (ctx, i) {
final d = demos[i];
final isSelected = i == selected;
return _RailTile(
demo: d,
selected: isSelected,
onTap: () => onSelect(i),
);
},
),
),
const Divider(height: 1),
Padding(
padding: const EdgeInsets.all(16),
child: Text(
'Click a demo to switch. Each panel is a focused example of one feature.',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
),
],
),
);
}
}
class _RailTile extends StatelessWidget {
const _RailTile({
required this.demo,
required this.selected,
required this.onTap,
});
final Demo demo;
final bool selected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Material(
color: selected
? theme.colorScheme.primaryContainer.withValues(alpha: 0.4)
: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
demo.icon,
size: 18,
color: selected
? theme.colorScheme.primary
: theme.colorScheme.onSurfaceVariant,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
demo.label,
style: theme.textTheme.bodyMedium?.copyWith(
fontWeight:
selected ? FontWeight.w600 : FontWeight.w400,
color: selected ? theme.colorScheme.primary : null,
),
),
const SizedBox(height: 2),
Text(
demo.blurb,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
),
),
);
}
}