Overlay
Dialog
A modal dialog interrupts the user with important content and expects a response.
dart run forui snippet create adaptive-dialog1class DialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: AdaptiveDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 body: const Text(16 'This action cannot be undone. This will permanently delete your account and '17 'remove your data from our servers.',18 ),19 actions: [20 FButton(21 size: .sm,22 child: const Text('Continue'),23 onPress: () => Navigator.of(context).pop(),24 ),25 FButton(26 variant: .outline,27 size: .sm,28 child: const Text('Cancel'),29 onPress: () => Navigator.of(context).pop(),30 ),31 ],32 ),33 ),34 ),35 child: const Text('Show Dialog'),36 );37}3839class AdaptiveDialog extends StatelessWidget {40 final FDialogStyleDelta style;41 final Animation<double>? animation;42 final Widget title;43 final Widget body;44 final List<Widget> actions;45 const AdaptiveDialog({46 required this.title,47 required this.body,48 required this.actions,49 this.style = const .context(),50 this.animation,51 super.key,52 });53 @override54 Widget build(BuildContext context) => FDialog.adaptive(55 style: style,56 animation: animation,57 horizontalBuilder: (context, style) {58 final touch = context.platformVariant.touch;59 return Padding(60 padding: touch61 ? const .symmetric(horizontal: 16, vertical: 18)62 : const .symmetric(horizontal: 16, vertical: 14),63 child: Column(64 crossAxisAlignment: .start,65 mainAxisSize: .min,66 children: [67 Padding(68 padding: touch69 ? const .only(left: 8, right: 8, bottom: 9)70 : const .only(bottom: 5),71 child: DefaultTextStyle.merge(72 style: style.titleTextStyle,73 child: title,74 ),75 ),76 Flexible(77 child: Padding(78 padding: touch79 ? const .only(left: 8, right: 8, bottom: 20)80 : const .only(bottom: 16),81 child: DefaultTextStyle.merge(82 style: style.bodyTextStyle,83 child: body,84 ),85 ),86 ),87 Row(88 mainAxisAlignment: .end,89 spacing: touch ? 10 : 8,90 children: touch91 ? [for (final action in actions) Expanded(child: action)]92 : actions,93 ),94 ],95 ),96 );97 },98 verticalBuilder: (context, style) {99 final touch = context.platformVariant.touch;100 return Padding(101 padding: touch102 ? const .symmetric(horizontal: 16, vertical: 18)103 : const .symmetric(horizontal: 16, vertical: 14),104 child: Column(105 crossAxisAlignment: .start,106 mainAxisSize: .min,107 children: [108 Padding(109 padding: touch110 ? const .only(left: 8, right: 8, bottom: 9)111 : const .only(left: 8, right: 8, bottom: 5),112 child: DefaultTextStyle.merge(113 style: style.titleTextStyle,114 child: title,115 ),116 ),117 Flexible(118 child: Padding(119 padding: touch120 ? const .only(left: 8, right: 8, bottom: 20)121 : const .only(left: 8, right: 8, bottom: 16),122 child: DefaultTextStyle.merge(123 style: style.bodyTextStyle,124 child: body,125 ),126 ),127 ),128 Column(129 mainAxisSize: .min,130 spacing: touch ? 10 : 8,131 children: actions,132 ),133 ],134 ),135 );136 },137 );138}139FDialog does not provide a built-in content layout. Generate one with the CLI or copy it from an example below, then
customize the widget directly.
CLI
To generate a specific style for customization:
dart run forui style create dialogdart run forui style create dialog-routeUsage
showFDialog(...)
1showFDialog(2 context: context,3 style: const .delta(insetPadding: .value(.zero)),4 routeStyle: const .delta(motion: .delta()),5 builder: (context, style, animation) => FDialog.adaptive(6 style: style,7 animation: animation,8 horizontalBuilder: (context, style) => const Text('Horizontal content'),9 verticalBuilder: (context, style) => const Text('Vertical content'),10 ),11)FDialog(...)
1FDialog(2 style: const .delta(insetPadding: .value(.zero)),3 clipBehavior: .none,4 builder: (context, style) => const Text('Custom content'),5)FDialog.adaptive(...)
1FDialog.adaptive(2 style: const .delta(insetPadding: .value(.zero)),3 clipBehavior: .none,4 horizontalBuilder: (context, style) => const Text('Horizontal content'),5 verticalBuilder: (context, style) => const Text('Vertical content'),6)Examples
Adaptive
Lays out the actions horizontally on wider devices and vertically on smaller ones.
Default
dart run forui snippet create adaptive-dialog1class DialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: AdaptiveDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 body: const Text(16 'This action cannot be undone. This will permanently delete your account and '17 'remove your data from our servers.',18 ),19 actions: [20 FButton(21 size: .sm,22 child: const Text('Continue'),23 onPress: () => Navigator.of(context).pop(),24 ),25 FButton(26 variant: .outline,27 size: .sm,28 child: const Text('Cancel'),29 onPress: () => Navigator.of(context).pop(),30 ),31 ],32 ),33 ),34 ),35 child: const Text('Show Dialog'),36 );37}3839class AdaptiveDialog extends StatelessWidget {40 final FDialogStyleDelta style;41 final Animation<double>? animation;42 final Widget title;43 final Widget body;44 final List<Widget> actions;45 const AdaptiveDialog({46 required this.title,47 required this.body,48 required this.actions,49 this.style = const .context(),50 this.animation,51 super.key,52 });53 @override54 Widget build(BuildContext context) => FDialog.adaptive(55 style: style,56 animation: animation,57 horizontalBuilder: (context, style) {58 final touch = context.platformVariant.touch;59 return Padding(60 padding: touch61 ? const .symmetric(horizontal: 16, vertical: 18)62 : const .symmetric(horizontal: 16, vertical: 14),63 child: Column(64 crossAxisAlignment: .start,65 mainAxisSize: .min,66 children: [67 Padding(68 padding: touch69 ? const .only(left: 8, right: 8, bottom: 9)70 : const .only(bottom: 5),71 child: DefaultTextStyle.merge(72 style: style.titleTextStyle,73 child: title,74 ),75 ),76 Flexible(77 child: Padding(78 padding: touch79 ? const .only(left: 8, right: 8, bottom: 20)80 : const .only(bottom: 16),81 child: DefaultTextStyle.merge(82 style: style.bodyTextStyle,83 child: body,84 ),85 ),86 ),87 Row(88 mainAxisAlignment: .end,89 spacing: touch ? 10 : 8,90 children: touch91 ? [for (final action in actions) Expanded(child: action)]92 : actions,93 ),94 ],95 ),96 );97 },98 verticalBuilder: (context, style) {99 final touch = context.platformVariant.touch;100 return Padding(101 padding: touch102 ? const .symmetric(horizontal: 16, vertical: 18)103 : const .symmetric(horizontal: 16, vertical: 14),104 child: Column(105 crossAxisAlignment: .start,106 mainAxisSize: .min,107 children: [108 Padding(109 padding: touch110 ? const .only(left: 8, right: 8, bottom: 9)111 : const .only(left: 8, right: 8, bottom: 5),112 child: DefaultTextStyle.merge(113 style: style.titleTextStyle,114 child: title,115 ),116 ),117 Flexible(118 child: Padding(119 padding: touch120 ? const .only(left: 8, right: 8, bottom: 20)121 : const .only(left: 8, right: 8, bottom: 16),122 child: DefaultTextStyle.merge(123 style: style.bodyTextStyle,124 child: body,125 ),126 ),127 ),128 Column(129 mainAxisSize: .min,130 spacing: touch ? 10 : 8,131 children: actions,132 ),133 ],134 ),135 );136 },137 );138}139Title
dart run forui snippet create adaptive-title-dialog1class AdaptiveTitleDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: AdaptiveTitleDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 actions: [16 FButton(17 size: .sm,18 child: const Text('Continue'),19 onPress: () => Navigator.of(context).pop(),20 ),21 FButton(22 variant: .outline,23 size: .sm,24 child: const Text('Cancel'),25 onPress: () => Navigator.of(context).pop(),26 ),27 ],28 ),29 ),30 ),31 child: const Text('Show Dialog'),32 );33}3435class AdaptiveTitleDialog extends StatelessWidget {36 final FDialogStyleDelta style;37 final Animation<double>? animation;38 final Widget title;39 final List<Widget> actions;40 const AdaptiveTitleDialog({41 required this.title,42 required this.actions,43 this.style = const .context(),44 this.animation,45 super.key,46 });47 @override48 Widget build(BuildContext context) => FDialog.adaptive(49 style: style,50 animation: animation,51 horizontalBuilder: (context, style) {52 final touch = context.platformVariant.touch;53 return Padding(54 padding: touch55 ? const .symmetric(horizontal: 16, vertical: 18)56 : const .symmetric(horizontal: 16, vertical: 14),57 child: Column(58 crossAxisAlignment: .start,59 mainAxisSize: .min,60 children: [61 Padding(62 padding: touch63 ? const .only(left: 8, right: 8, bottom: 20)64 : const .only(bottom: 16),65 child: DefaultTextStyle.merge(66 style: style.titleTextStyle,67 child: title,68 ),69 ),70 Row(71 mainAxisAlignment: .end,72 spacing: touch ? 10 : 8,73 children: touch74 ? [for (final action in actions) Expanded(child: action)]75 : actions,76 ),77 ],78 ),79 );80 },81 verticalBuilder: (context, style) {82 final touch = context.platformVariant.touch;83 return Padding(84 padding: touch85 ? const .symmetric(horizontal: 16, vertical: 18)86 : const .symmetric(horizontal: 16, vertical: 14),87 child: Column(88 crossAxisAlignment: .start,89 mainAxisSize: .min,90 children: [91 Padding(92 padding: touch93 ? const .only(left: 8, right: 8, bottom: 20)94 : const .only(left: 8, right: 8, bottom: 16),95 child: DefaultTextStyle.merge(96 style: style.titleTextStyle,97 child: title,98 ),99 ),100 Column(101 mainAxisSize: .min,102 spacing: touch ? 10 : 8,103 children: actions,104 ),105 ],106 ),107 );108 },109 );110}111Media
dart run forui snippet create adaptive-media-dialog1class AdaptiveMediaDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: AdaptiveMediaDialog(12 style: style,13 animation: animation,14 image: ClipRRect(15 borderRadius: context.theme.style.borderRadius.sm,16 child: Container(17 decoration: BoxDecoration(18 image: DecorationImage(19 image: AssetImage(path('avatar.png')),20 fit: .cover,21 ),22 ),23 height: 140,24 ),25 ),26 title: const Text('Gratitude'),27 body: const Text(28 'The quality of being thankful; readiness to show appreciation for and to return kindness.',29 ),30 actions: [31 FButton(32 size: .sm,33 child: const Text('Continue'),34 onPress: () => Navigator.of(context).pop(),35 ),36 FButton(37 variant: .outline,38 size: .sm,39 child: const Text('Cancel'),40 onPress: () => Navigator.of(context).pop(),41 ),42 ],43 ),44 ),45 ),46 child: const Text('Show Dialog'),47 );48}4950class AdaptiveMediaDialog extends StatelessWidget {51 final FDialogStyleDelta style;52 final Animation<double>? animation;53 final Widget image;54 final Widget title;55 final Widget body;56 final List<Widget> actions;57 const AdaptiveMediaDialog({58 required this.image,59 required this.title,60 required this.body,61 required this.actions,62 this.style = const .context(),63 this.animation,64 super.key,65 });66 @override67 Widget build(BuildContext context) => FDialog.adaptive(68 style: style,69 animation: animation,70 horizontalBuilder: (context, style) {71 final touch = context.platformVariant.touch;72 return Padding(73 padding: touch74 ? const .symmetric(horizontal: 16, vertical: 18)75 : const .symmetric(horizontal: 16, vertical: 14),76 child: Column(77 crossAxisAlignment: .start,78 mainAxisSize: .min,79 children: [80 image,81 Padding(82 padding: touch83 ? const .only(left: 8, right: 8, top: 9, bottom: 9)84 : const .only(top: 9, bottom: 5),85 child: DefaultTextStyle.merge(86 style: style.titleTextStyle,87 child: title,88 ),89 ),90 Flexible(91 child: Padding(92 padding: touch93 ? const .only(left: 8, right: 8, bottom: 20)94 : const .only(bottom: 16),95 child: DefaultTextStyle.merge(96 style: style.bodyTextStyle,97 child: body,98 ),99 ),100 ),101 Row(102 mainAxisAlignment: .end,103 spacing: touch ? 10 : 8,104 children: touch105 ? [for (final action in actions) Expanded(child: action)]106 : actions,107 ),108 ],109 ),110 );111 },112 verticalBuilder: (context, style) {113 final touch = context.platformVariant.touch;114 return Padding(115 padding: touch116 ? const .symmetric(horizontal: 16, vertical: 18)117 : const .symmetric(horizontal: 16, vertical: 14),118 child: Column(119 crossAxisAlignment: .start,120 mainAxisSize: .min,121 children: [122 image,123 Padding(124 padding: touch125 ? const .only(left: 8, right: 8, top: 9, bottom: 9)126 : const .only(left: 8, right: 8, top: 9, bottom: 5),127 child: DefaultTextStyle.merge(128 style: style.titleTextStyle,129 child: title,130 ),131 ),132 Flexible(133 child: Padding(134 padding: touch135 ? const .only(left: 8, right: 8, bottom: 20)136 : const .only(left: 8, right: 8, bottom: 16),137 child: DefaultTextStyle.merge(138 style: style.bodyTextStyle,139 child: body,140 ),141 ),142 ),143 Column(144 mainAxisSize: .min,145 spacing: touch ? 10 : 8,146 children: actions,147 ),148 ],149 ),150 );151 },152 );153}154Horizontal
Lays out the actions horizontally. Recommended for desktop and wider devices
default
dart run forui snippet create horizontal-dialog1class HorizontalDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: HorizontalDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 body: const Text(16 'This action cannot be undone. This will permanently delete your account and '17 'remove your data from our servers.',18 ),19 actions: [20 FButton(21 size: .sm,22 child: const Text('Continue'),23 onPress: () => Navigator.of(context).pop(),24 ),25 FButton(26 variant: .outline,27 size: .sm,28 child: const Text('Cancel'),29 onPress: () => Navigator.of(context).pop(),30 ),31 ],32 ),33 ),34 ),35 child: const Text('Show Dialog'),36 );37}3839class HorizontalDialog extends StatelessWidget {40 final FDialogStyleDelta style;41 final Animation<double>? animation;42 final Widget title;43 final Widget body;44 final List<Widget> actions;45 const HorizontalDialog({46 required this.title,47 required this.body,48 required this.actions,49 this.style = const .context(),50 this.animation,51 super.key,52 });53 @override54 Widget build(BuildContext context) => FDialog(55 style: style,56 animation: animation,57 builder: (context, style) {58 final touch = context.platformVariant.touch;59 return Padding(60 padding: touch61 ? const .symmetric(horizontal: 16, vertical: 18)62 : const .symmetric(horizontal: 16, vertical: 14),63 child: Column(64 crossAxisAlignment: .start,65 mainAxisSize: .min,66 children: [67 Padding(68 padding: touch69 ? const .only(left: 8, right: 8, bottom: 9)70 : const .only(bottom: 5),71 child: DefaultTextStyle.merge(72 style: style.titleTextStyle,73 child: title,74 ),75 ),76 Flexible(77 child: Padding(78 padding: touch79 ? const .only(left: 8, right: 8, bottom: 20)80 : const .only(bottom: 16),81 child: DefaultTextStyle.merge(82 style: style.bodyTextStyle,83 child: body,84 ),85 ),86 ),87 Row(88 mainAxisAlignment: .end,89 spacing: touch ? 10 : 8,90 children: touch91 ? [for (final action in actions) Expanded(child: action)]92 : actions,93 ),94 ],95 ),96 );97 },98 );99}100Title
dart run forui snippet create horizontal-title-dialog1class HorizontalTitleDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: HorizontalTitleDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 actions: [16 FButton(17 size: .sm,18 child: const Text('Continue'),19 onPress: () => Navigator.of(context).pop(),20 ),21 FButton(22 variant: .outline,23 size: .sm,24 child: const Text('Cancel'),25 onPress: () => Navigator.of(context).pop(),26 ),27 ],28 ),29 ),30 ),31 child: const Text('Show Dialog'),32 );33}3435class HorizontalTitleDialog extends StatelessWidget {36 final FDialogStyleDelta style;37 final Animation<double>? animation;38 final Widget title;39 final List<Widget> actions;40 const HorizontalTitleDialog({41 required this.title,42 required this.actions,43 this.style = const .context(),44 this.animation,45 super.key,46 });47 @override48 Widget build(BuildContext context) => FDialog(49 style: style,50 animation: animation,51 builder: (context, style) {52 final touch = context.platformVariant.touch;53 return Padding(54 padding: touch55 ? const .symmetric(horizontal: 16, vertical: 18)56 : const .symmetric(horizontal: 16, vertical: 14),57 child: Column(58 crossAxisAlignment: .start,59 mainAxisSize: .min,60 children: [61 Padding(62 padding: touch63 ? const .only(left: 8, right: 8, bottom: 20)64 : const .only(bottom: 16),65 child: DefaultTextStyle.merge(66 style: style.titleTextStyle,67 child: title,68 ),69 ),70 Row(71 mainAxisAlignment: .end,72 spacing: touch ? 10 : 8,73 children: touch74 ? [for (final action in actions) Expanded(child: action)]75 : actions,76 ),77 ],78 ),79 );80 },81 );82}83Media
dart run forui snippet create horizontal-media-dialog1class HorizontalMediaDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: HorizontalMediaDialog(12 style: style,13 animation: animation,14 image: ClipRRect(15 borderRadius: context.theme.style.borderRadius.sm,16 child: Container(17 decoration: BoxDecoration(18 image: DecorationImage(19 image: AssetImage(path('avatar.png')),20 fit: .cover,21 ),22 ),23 height: 140,24 ),25 ),26 title: const Text('Gratitude'),27 body: const Text(28 'The quality of being thankful; readiness to show appreciation for and to return kindness.',29 ),30 actions: [31 FButton(32 size: .sm,33 child: const Text('Continue'),34 onPress: () => Navigator.of(context).pop(),35 ),36 FButton(37 variant: .outline,38 size: .sm,39 child: const Text('Cancel'),40 onPress: () => Navigator.of(context).pop(),41 ),42 ],43 ),44 ),45 ),46 child: const Text('Show Dialog'),47 );48}4950class HorizontalMediaDialog extends StatelessWidget {51 final FDialogStyleDelta style;52 final Animation<double>? animation;53 final Widget image;54 final Widget title;55 final Widget body;56 final List<Widget> actions;57 const HorizontalMediaDialog({58 required this.image,59 required this.title,60 required this.body,61 required this.actions,62 this.style = const .context(),63 this.animation,64 super.key,65 });66 @override67 Widget build(BuildContext context) => FDialog(68 style: style,69 animation: animation,70 builder: (context, style) {71 final touch = context.platformVariant.touch;72 return Padding(73 padding: touch74 ? const .symmetric(horizontal: 16, vertical: 18)75 : const .symmetric(horizontal: 16, vertical: 14),76 child: Column(77 crossAxisAlignment: .start,78 mainAxisSize: .min,79 children: [80 image,81 Padding(82 padding: touch83 ? const .only(left: 8, right: 8, top: 9, bottom: 9)84 : const .only(top: 9, bottom: 5),85 child: DefaultTextStyle.merge(86 style: style.titleTextStyle,87 child: title,88 ),89 ),90 Flexible(91 child: Padding(92 padding: touch93 ? const .only(left: 8, right: 8, bottom: 20)94 : const .only(bottom: 16),95 child: DefaultTextStyle.merge(96 style: style.bodyTextStyle,97 child: body,98 ),99 ),100 ),101 Row(102 mainAxisAlignment: .end,103 spacing: touch ? 10 : 8,104 children: touch105 ? [for (final action in actions) Expanded(child: action)]106 : actions,107 ),108 ],109 ),110 );111 },112 );113}114Vertical
Lays out the actions vertically. Recommended for mobile devices.
Default
dart run forui snippet create vertical-dialog1class VerticalDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: VerticalDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 body: const Text(16 'This action cannot be undone. This will permanently delete your account and '17 'remove your data from our servers.',18 ),19 actions: [20 FButton(21 size: .sm,22 child: const Text('Continue'),23 onPress: () => Navigator.of(context).pop(),24 ),25 FButton(26 variant: .outline,27 size: .sm,28 child: const Text('Cancel'),29 onPress: () => Navigator.of(context).pop(),30 ),31 ],32 ),33 ),34 ),35 child: const Text('Show Dialog'),36 );37}3839class VerticalDialog extends StatelessWidget {40 final FDialogStyleDelta style;41 final Animation<double>? animation;42 final Widget title;43 final Widget body;44 final List<Widget> actions;45 const VerticalDialog({46 required this.title,47 required this.body,48 required this.actions,49 this.style = const .context(),50 this.animation,51 super.key,52 });53 @override54 Widget build(BuildContext context) => FDialog(55 style: style,56 animation: animation,57 builder: (context, style) {58 final touch = context.platformVariant.touch;59 return Padding(60 padding: touch61 ? const .symmetric(horizontal: 16, vertical: 18)62 : const .symmetric(horizontal: 16, vertical: 14),63 child: Column(64 crossAxisAlignment: .start,65 mainAxisSize: .min,66 children: [67 Padding(68 padding: touch69 ? const .only(left: 8, right: 8, bottom: 9)70 : const .only(left: 8, right: 8, bottom: 5),71 child: DefaultTextStyle.merge(72 style: style.titleTextStyle,73 child: title,74 ),75 ),76 Flexible(77 child: Padding(78 padding: touch79 ? const .only(left: 8, right: 8, bottom: 20)80 : const .only(left: 8, right: 8, bottom: 16),81 child: DefaultTextStyle.merge(82 style: style.bodyTextStyle,83 child: body,84 ),85 ),86 ),87 Column(88 mainAxisSize: .min,89 spacing: touch ? 10 : 8,90 children: actions,91 ),92 ],93 ),94 );95 },96 );97}98Title
dart run forui snippet create vertical-title-dialog1class VerticalTitleDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: VerticalTitleDialog(12 style: style,13 animation: animation,14 title: const Text('Are you absolutely sure?'),15 actions: [16 FButton(17 size: .sm,18 child: const Text('Continue'),19 onPress: () => Navigator.of(context).pop(),20 ),21 FButton(22 variant: .outline,23 size: .sm,24 child: const Text('Cancel'),25 onPress: () => Navigator.of(context).pop(),26 ),27 ],28 ),29 ),30 ),31 child: const Text('Show Dialog'),32 );33}3435class VerticalTitleDialog extends StatelessWidget {36 final FDialogStyleDelta style;37 final Animation<double>? animation;38 final Widget title;39 final List<Widget> actions;40 const VerticalTitleDialog({41 required this.title,42 required this.actions,43 this.style = const .context(),44 this.animation,45 super.key,46 });47 @override48 Widget build(BuildContext context) => FDialog(49 style: style,50 animation: animation,51 builder: (context, style) {52 final touch = context.platformVariant.touch;53 return Padding(54 padding: touch55 ? const .symmetric(horizontal: 16, vertical: 18)56 : const .symmetric(horizontal: 16, vertical: 14),57 child: Column(58 crossAxisAlignment: .start,59 mainAxisSize: .min,60 children: [61 Padding(62 padding: touch63 ? const .only(left: 8, right: 8, bottom: 20)64 : const .only(left: 8, right: 8, bottom: 16),65 child: DefaultTextStyle.merge(66 style: style.titleTextStyle,67 child: title,68 ),69 ),70 Column(71 mainAxisSize: .min,72 spacing: touch ? 10 : 8,73 children: actions,74 ),75 ],76 ),77 );78 },79 );80}81Media
dart run forui snippet create vertical-media-dialog1class VerticalMediaDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 builder: (context, style, animation) => FTheme(10 data: theme,11 child: VerticalMediaDialog(12 style: style,13 animation: animation,14 image: ClipRRect(15 borderRadius: context.theme.style.borderRadius.sm,16 child: Container(17 decoration: BoxDecoration(18 image: DecorationImage(19 image: AssetImage(path('avatar.png')),20 fit: .cover,21 ),22 ),23 height: 140,24 ),25 ),26 title: const Text('Gratitude'),27 body: const Text(28 'The quality of being thankful; readiness to show appreciation for and to return kindness.',29 ),30 actions: [31 FButton(32 size: .sm,33 child: const Text('Continue'),34 onPress: () => Navigator.of(context).pop(),35 ),36 FButton(37 variant: .outline,38 size: .sm,39 child: const Text('Cancel'),40 onPress: () => Navigator.of(context).pop(),41 ),42 ],43 ),44 ),45 ),46 child: const Text('Show Dialog'),47 );48}4950class VerticalMediaDialog extends StatelessWidget {51 final FDialogStyleDelta style;52 final Animation<double>? animation;53 final Widget image;54 final Widget title;55 final Widget body;56 final List<Widget> actions;57 const VerticalMediaDialog({58 required this.image,59 required this.title,60 required this.body,61 required this.actions,62 this.style = const .context(),63 this.animation,64 super.key,65 });66 @override67 Widget build(BuildContext context) => FDialog(68 style: style,69 animation: animation,70 builder: (context, style) {71 final touch = context.platformVariant.touch;72 return Padding(73 padding: touch74 ? const .symmetric(horizontal: 16, vertical: 18)75 : const .symmetric(horizontal: 16, vertical: 14),76 child: Column(77 crossAxisAlignment: .start,78 mainAxisSize: .min,79 children: [80 image,81 Padding(82 padding: touch83 ? const .only(left: 8, right: 8, top: 9, bottom: 9)84 : const .only(left: 8, right: 8, top: 9, bottom: 5),85 child: DefaultTextStyle.merge(86 style: style.titleTextStyle,87 child: title,88 ),89 ),90 Flexible(91 child: Padding(92 padding: touch93 ? const .only(left: 8, right: 8, bottom: 20)94 : const .only(left: 8, right: 8, bottom: 16),95 child: DefaultTextStyle.merge(96 style: style.bodyTextStyle,97 child: body,98 ),99 ),100 ),101 Column(102 mainAxisSize: .min,103 spacing: touch ? 10 : 8,104 children: actions,105 ),106 ],107 ),108 );109 },110 );111}112Blurred Barrier
1class BlurredDialogExample extends StatelessWidget {2 @override3 Widget build(BuildContext context) => FButton(4 variant: .outline,5 size: .sm,6 mainAxisSize: .min,7 onPress: () => showFDialog(8 context: context,9 routeStyle: .delta(10 barrierFilter: () =>11 (animation) => ImageFilter.compose(12 outer: ImageFilter.blur(13 sigmaX: animation * 5,14 sigmaY: animation * 5,15 ),16 inner: ColorFilter.mode(context.theme.colors.barrier, .srcOver),17 ),18 ),19 builder: (context, style, animation) => FTheme(20 data: theme,21 child: VerticalDialog(22 style: style,23 animation: animation,24 title: const Text('Are you absolutely sure?'),25 body: const Text(26 'This action cannot be undone. This will permanently delete your account and '27 'remove your data from our servers.',28 ),29 actions: [30 FButton(31 size: .sm,32 child: const Text('Continue'),33 onPress: () => Navigator.of(context).pop(),34 ),35 FButton(36 size: .sm,37 variant: .outline,38 child: const Text('Cancel'),39 onPress: () => Navigator.of(context).pop(),40 ),41 ],42 ),43 ),44 ),45 child: const Text('Show Dialog'),46 );47}4849class VerticalDialog extends StatelessWidget {50 final FDialogStyleDelta style;51 final Animation<double>? animation;52 final Widget title;53 final Widget body;54 final List<Widget> actions;55 const VerticalDialog({56 required this.title,57 required this.body,58 required this.actions,59 this.style = const .context(),60 this.animation,61 super.key,62 });63 @override64 Widget build(BuildContext context) => FDialog(65 style: style,66 animation: animation,67 builder: (context, style) {68 final touch = context.platformVariant.touch;69 return Padding(70 padding: touch71 ? const .symmetric(horizontal: 16, vertical: 18)72 : const .symmetric(horizontal: 16, vertical: 14),73 child: Column(74 crossAxisAlignment: .start,75 mainAxisSize: .min,76 children: [77 Padding(78 padding: touch79 ? const .only(left: 8, right: 8, bottom: 9)80 : const .only(left: 8, right: 8, bottom: 5),81 child: DefaultTextStyle.merge(82 style: style.titleTextStyle,83 child: title,84 ),85 ),86 Flexible(87 child: Padding(88 padding: touch89 ? const .only(left: 8, right: 8, bottom: 20)90 : const .only(left: 8, right: 8, bottom: 16),91 child: DefaultTextStyle.merge(92 style: style.bodyTextStyle,93 child: body,94 ),95 ),96 ),97 Column(98 mainAxisSize: .min,99 spacing: touch ? 10 : 8,100 children: actions,101 ),102 ],103 ),104 );105 },106 );107}108