Custom widgets guide
Learn how to create and use custom Flutter widgets in SuperDeck presentations
Custom widgets guide
Render custom Flutter widgets from Markdown. Register widgets in DeckOptions.widgets, then use them in slides.md.
Markdown syntax
Two equivalent forms:
- Shorthand (recommended) -
@twitter { ... } - Explicit -
@widget { name: "twitter" ... }
All properties pass to WidgetDefinition.parse() as arguments.
Simple: map args (no validation)
import 'package:flutter/widgets.dart';
import 'package:superdeck/superdeck.dart';
class TwitterWidgetDefinition extends WidgetDefinition<Map<String, Object?>> {
const TwitterWidgetDefinition();
@override
Map<String, Object?> parse(Map<String, Object?> args) => args;
@override
Widget build(BuildContext context, Map<String, Object?> args) {
final username = args['username'] as String? ?? '';
final tweetId = args['tweetId'] as String? ?? '';
return Text('Twitter: @$username ($tweetId)');
}
}
Recommended: typed args with validation
Validate and convert the raw map to a typed args object in parse(). Use Ack (from superdeck_core) for schema validation.
import 'package:flutter/widgets.dart';
import 'package:superdeck/superdeck.dart';
class TwitterArgs {
const TwitterArgs({required this.username, required this.tweetId});
final String username;
final String tweetId;
static final schema = Ack.object({
'username': Ack.string().notEmpty(),
'tweetId': Ack.string().notEmpty(),
});
static TwitterArgs parse(Map<String, Object?> map) {
schema.parse(map);
return TwitterArgs(
username: map['username'] as String,
tweetId: map['tweetId'] as String,
);
}
}
class TwitterDefinition extends WidgetDefinition<TwitterArgs> {
const TwitterDefinition();
@override
TwitterArgs parse(Map<String, Object?> args) => TwitterArgs.parse(args);
@override
Widget build(BuildContext context, TwitterArgs args) {
return Text('Twitter: @${args.username} (${args.tweetId})');
}
}
Register widgets in DeckOptions
import 'package:flutter/widgets.dart';
import 'package:superdeck/superdeck.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SuperDeckApp.initialize();
runApp(
SuperDeckApp(
options: DeckOptions(
widgets: const {
'twitter': TwitterWidgetDefinition(),
},
),
),
);
}
Use widgets in slides.md
Shorthand:
@twitter {
username: "flutterdev"
tweetId: "1234567890"
}
Explicit:
@widget {
name: "twitter"
username: "flutterdev"
tweetId: "1234567890"
}
Access block and slide context
In WidgetDefinition.build():
BlockConfiguration.of(context)- Block size, alignment, slide specSlideConfiguration.of(context)- Slide index, options, metadata
@override
Widget build(BuildContext context, TwitterArgs args) {
final block = BlockConfiguration.of(context);
final slide = SlideConfiguration.of(context);
return SizedBox(
width: block.size.width,
height: block.size.height,
child: Text('Slide ${slide.slideIndex + 1}: @${args.username}'),
);
}