Skip to content

Instantly share code, notes, and snippets.

@jonahwilliams
Created October 18, 2023 01:14
Show Gist options
  • Save jonahwilliams/3aa17affa01ba141199aced7c1999040 to your computer and use it in GitHub Desktop.
Save jonahwilliams/3aa17affa01ba141199aced7c1999040 to your computer and use it in GitHub Desktop.
typedef AdaptiveThemeCallback<T> = T Function(ThemeData theme, T defaultValue);
class ThemeMapper<T> {
ThemeMapper(this.callback);
final AdaptiveThemeCallback<T> callback;
Type get type => T;
T invoke(ThemeData theme, T defaultValue) {
return callback(theme, defaultValue);
}
}
class AdaptiveThemeDelegate {
const AdaptiveThemeDelegate._() : callbacks_ = const {};
AdaptiveThemeDelegate(List<ThemeMapper<Object?>> mappers) : callbacks_ = {} {
for (var mapper in mappers) {
callbacks_[mapper.type] = mapper;
}
}
static const defaultDelegate = AdaptiveThemeDelegate._();
final Map<Type, ThemeMapper<Object?>> callbacks_;
T adaptive<T>(ThemeData theme, T defaultValue) {
ThemeMapper<Object?>? mapper = callbacks_[T];
if (mapper == null) {
return defaultValue;
}
return (mapper as ThemeMapper<T>).invoke(theme, defaultValue);
}
}
T defaultCallback<T>(ThemeData theme, T defaultValue) => defaultValue;
class ThemeData {
factory ThemeData({AdaptiveThemeDelegate? callback}) {
return ThemeData.raw(
callback: callback ?? AdaptiveThemeDelegate.defaultDelegate);
}
const ThemeData.raw({this.callback = AdaptiveThemeDelegate.defaultDelegate});
final AdaptiveThemeDelegate callback;
T adaptive<T>(T defaultValue) => callback.adaptive<T>(this, defaultValue);
}
String myCallback(ThemeData theme, String defaultValue) {
return 'I am an adaptive theme';
}
void main() {
// Unfortunately, at this point myCallback's type parameters become `dynamic`
final ThemeData myTheme = ThemeData(callback: AdaptiveThemeDelegate([
ThemeMapper<String>(myCallback)
]));
// Foo.adaptive gets its version of the theme like this:
print(myTheme.adaptive<String>('I am a theme'));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment