Skip to content

Commit

Permalink
feat: platform builder widget add
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Nov 3, 2022
1 parent 8193e1c commit 2fdbfae
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 17 deletions.
64 changes: 47 additions & 17 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';

Expand Down Expand Up @@ -250,27 +251,56 @@ class _MyHomePageState extends State<MyHomePage> {
"This is a platform-specific dialog",
),
primaryActions: [
PlatformFilledButton(
child: const PlatformText("Yes"),
onPressed: () {
Navigator.of(context).pop(true);
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, _) {
return PlatformFilledButton(
child: const PlatformText("Yes"),
onPressed: () {
Navigator.of(context).pop(true);
},
);
},
ios: (context, parent) {
return CupertinoDialogAction(
isDefaultAction: true,
child: const PlatformText("Yes"),
onPressed: () {
Navigator.of(context).pop(true);
},
);
},
),
],
secondaryActions: [
PlatformFilledButton(
isSecondary: true,
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(
Colors.grey[300],
),
),
child: const PlatformText(
"No",
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop(false);
PlatformBuilder(
fallback: PlatformBuilderFallback.android,
android: (context, parent) {
return PlatformFilledButton(
isSecondary: true,
style: ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(
Colors.grey[300],
),
),
child: const PlatformText(
"No",
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop(false);
},
);
},
ios: (context, parent) {
return CupertinoDialogAction(
isDestructiveAction: true,
child: const PlatformText("No"),
onPressed: () {
Navigator.of(context).pop(false);
},
);
},
),
],
Expand Down
1 change: 1 addition & 0 deletions lib/platform_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export 'src/platform_circular_progress_indicator.dart';
export 'src/platform_text.dart';
export 'src/platform_alert_dialog.dart';
export 'src/platform_checkbox.dart';
export 'src/platform_builder.dart';
98 changes: 98 additions & 0 deletions lib/src/platform_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:platform_ui/platform_ui.dart';

typedef PlatformWidgetBuilder<T> = Widget Function(
BuildContext context, T data);

enum PlatformBuilderFallback {
android,
ios,
macos,
linux,
windows,
}

class PlatformBuilder<T> extends StatelessWidget {
final PlatformWidgetBuilder<T>? android;
final PlatformWidgetBuilder<T>? ios;
final PlatformWidgetBuilder<T>? macos;
final PlatformWidgetBuilder<T>? linux;
final PlatformWidgetBuilder<T>? windows;
final T Function(BuildContext context)? data;
final PlatformBuilderFallback? fallback;

const PlatformBuilder({
Key? key,
this.data,
this.android,
this.ios,
this.macos,
this.linux,
this.windows,
this.fallback,
}) : assert(
android != null ||
ios != null ||
macos != null ||
linux != null ||
windows != null,
'At least one platform must be specified',
),
assert(
fallback == null ||
(fallback == PlatformBuilderFallback.android &&
android != null) ||
(fallback == PlatformBuilderFallback.ios && ios != null) ||
(fallback == PlatformBuilderFallback.macos && macos != null) ||
(fallback == PlatformBuilderFallback.linux && linux != null) ||
(fallback == PlatformBuilderFallback.windows && windows != null),
"The builder for provided fallback `$fallback` can't be null",
),
super(key: key);

PlatformWidgetBuilder<T>? getByFallback() {
switch (fallback) {
case PlatformBuilderFallback.android:
return android;
case PlatformBuilderFallback.ios:
return ios;
case PlatformBuilderFallback.macos:
return macos;
case PlatformBuilderFallback.linux:
return linux;
case PlatformBuilderFallback.windows:
return windows;
default:
return null;
}
}

@override
Widget build(BuildContext context) {
final data = this.data?.call(context);
final fallback = getByFallback();
if (kIsWeb) {
return (windows ?? fallback ?? macos ?? linux ?? android ?? ios)!(
context, data as T);
}
switch (platform ?? defaultTargetPlatform) {
case TargetPlatform.iOS:
return (ios ?? fallback ?? android ?? macos ?? windows ?? linux)!(
context, data as T);
case TargetPlatform.macOS:
return (macos ?? fallback ?? windows ?? linux ?? ios ?? android)!(
context, data as T);
case TargetPlatform.windows:
return (windows ?? fallback ?? linux ?? macos ?? android ?? ios)!(
context, data as T);
case TargetPlatform.linux:
return (linux ?? fallback ?? windows ?? macos ?? android ?? ios)!(
context, data as T);
case TargetPlatform.android:
default:
return (android ?? fallback ?? ios ?? windows ?? macos ?? linux)!(
context, data as T);
}
}
}

0 comments on commit 2fdbfae

Please sign in to comment.