Skip to content

Commit

Permalink
Added missing docs
Browse files Browse the repository at this point in the history
  • Loading branch information
sunarya-thito committed Oct 26, 2024
1 parent 1429633 commit 83cd8f4
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/src/async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,27 @@ typedef FutureWidgetBuilderLoadingCallback = Widget Function(
typedef FutureWidgetBuilderEmptyCallback = Widget Function(
BuildContext context);

/// A widget that builds itself based on the latest snapshot of interaction with
class FutureWidgetBuilder<T> extends StatelessWidget {
/// The future to which this builder is currently connected.
final Future<T>? future;

/// The builder that will be called when the future is completed with a value.
final FutureWidgetBuilderCallback<T> builder;

/// The builder that will be called when the future is completed with an error.
final FutureWidgetBuilderErrorCallback? errorBuilder;

/// The builder that will be called when the future is still loading.
final FutureWidgetBuilderLoadingCallback? loadingBuilder;

/// The builder that will be called when the future is completed with no data.
final FutureWidgetBuilderEmptyCallback? emptyBuilder;

/// The initial data to be used when the future is not completed.
final T? initialData;

/// Create a FutureWidgetBuilder.
const FutureWidgetBuilder({
super.key,
this.initialData,
Expand Down
48 changes: 48 additions & 0 deletions lib/src/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1096,36 +1096,45 @@ class ModelListenable<T> extends StatelessWidget
class ModelKey<T> {
final Symbol key;

/// Creates a ModelKey.
const ModelKey(this.key);

/// {@macro Model.maybeOf}
T? maybeOf(BuildContext context) {
return MultiModel.maybeOf<T>(context, key);
}

/// {@macro Model.of}
T of(BuildContext context) {
return MultiModel.of<T>(context, key);
}

/// {@macro Model.maybeFind}
T? maybeFind(BuildContext context) {
return MultiModel.maybeFind<T>(context, key);
}

/// {@macro Model.find}
T find(BuildContext context) {
return MultiModel.find<T>(context, key);
}

/// {@macro Model.maybeChange}
void maybeChange(BuildContext context, T data) {
MultiModel.maybeChange(context, key, data);
}

/// {@macro Model.change}
void change(BuildContext context, T data) {
MultiModel.change(context, key, data);
}

/// {@macro Model.maybeFindProperty}
ModelProperty<T>? maybeFindProperty(BuildContext context) {
return MultiModel.maybeFindProperty<T>(context, key);
}

/// {@macro Model.find}
ModelProperty<T> findProperty(BuildContext context) {
return MultiModel.findProperty<T>(context, key);
}
Expand Down Expand Up @@ -1173,22 +1182,27 @@ class MultiModel extends StatelessWidget {
);
}

/// {@macro Model.maybeOf}
static T? maybeOf<T>(BuildContext context, Symbol key) {
return maybeOfProperty<T>(context, key)?.value;
}

/// {@macro Model.of}
static T of<T>(BuildContext context, Symbol key) {
return ofProperty<T>(context, key).value;
}

/// {@macro Model.maybeFind}
static T? maybeFind<T>(BuildContext context, Symbol key) {
return maybeOfProperty<T>(context, key)?.value;
}

/// {@macro Model.find}
static T find<T>(BuildContext context, Symbol key) {
return findProperty<T>(context, key).value;
}

/// {@macro Model.change}
static void change<T>(BuildContext context, Symbol key, T data) {
final widget = context.findAncestorWidgetOfExactType<_InheritedModel>();
assert(widget != null, 'No Model<$T>($key) found in context');
Expand All @@ -1201,6 +1215,7 @@ class MultiModel extends StatelessWidget {
assert(false, 'No Model<$T>($key) found in context');
}

/// {@macro Model.maybeFindProperty}
static bool maybeChange<T>(BuildContext context, Symbol key, T data) {
final widget = context.findAncestorWidgetOfExactType<_InheritedModel>();
if (widget == null) {
Expand All @@ -1215,6 +1230,7 @@ class MultiModel extends StatelessWidget {
return false;
}

/// {@macro Model.ofProperty}
static ModelProperty<T>? maybeFindProperty<T>(
BuildContext context, Symbol key) {
final widget = context.findAncestorWidgetOfExactType<_InheritedModel>();
Expand All @@ -1232,12 +1248,14 @@ class MultiModel extends StatelessWidget {
return null;
}

/// {@macro Model.findProperty}
static ModelProperty<T> findProperty<T>(BuildContext context, Symbol key) {
final model = maybeFindProperty<T>(context, key);
assert(model != null, 'No Model<$T>($key) found in context');
return model!;
}

/// {@macro Model.maybeOfProperty}
static ModelProperty<T>? maybeOfProperty<T>(
BuildContext context, Symbol key) {
var model = InheritedModel.inheritFrom<_InheritedModel>(context,
Expand All @@ -1256,6 +1274,7 @@ class MultiModel extends StatelessWidget {
return null;
}

/// {@macro Model.ofProperty}
static ModelProperty<T> ofProperty<T>(BuildContext context, Symbol key) {
final model = maybeOfProperty<T>(context, key);
assert(model != null, 'No Model<$T>($key) found in context');
Expand Down Expand Up @@ -1346,14 +1365,22 @@ class _InheritedModel extends InheritedModel<ModelKey> {
}
}

/// A callback that takes the model and returns a widget.
typedef ModelWidgetBuilder<T> = Widget Function(
BuildContext context, ModelProperty<T> model, Widget? child);

/// A widget that uses the model to build a widget.
class ModelBuilder<T> extends StatelessWidget {
/// The data key of the model.
final Symbol dataKey;

/// The builder callback that takes the model and returns a widget.
final ModelWidgetBuilder<T> builder;

/// The child widget.
final Widget? child;

/// Creates a ModelBuilder.
const ModelBuilder(
this.dataKey, {
super.key,
Expand All @@ -1369,13 +1396,18 @@ class ModelBuilder<T> extends StatelessWidget {
}
}

/// An interface to provide a way to notify listeners.
abstract class ChangeListener {
/// Dispatches the event to the listener.
void dispatch(Object? event);
}

/// A callback that takes no arguments and returns no data.
class VoidChangeListener extends ChangeListener {
/// The listener callback.
final VoidCallback listener;

/// Creates a VoidChangeListener.
VoidChangeListener(this.listener);

@override
Expand All @@ -1393,6 +1425,7 @@ class VoidChangeListener extends ChangeListener {
int get hashCode => listener.hashCode;
}

/// A mixin that provides a way to notify listeners.
mixin ChangesNotifierHelperMixin {
int _count = 0;
static final List<ChangeListener?> _emptyListeners =
Expand All @@ -1405,6 +1438,7 @@ mixin ChangesNotifierHelperMixin {

bool _creationDispatched = false;

/// A debug assertion to check if the object is disposed.
static bool debugAssertNotDisposed(ChangesNotifierHelperMixin notifier) {
assert(() {
if (notifier._debugDisposed) {
Expand All @@ -1419,11 +1453,17 @@ mixin ChangesNotifierHelperMixin {
return true;
}

/// Whether the object has listeners.
@protected
bool get hasListeners {
return _count > 0;
}

/// Report that the object has been created.
/// This method is called by the object itself to report that it has been
/// created. This is used to track memory allocations.
/// This method is only called if kFlutterMemoryAllocationsEnabled is true.
/// - [object] The object that has been created.
@protected
static void maybeDispatchObjectCreation(ChangesNotifierHelperMixin object) {
// Tree shaker does not include this method and the class MemoryAllocations
Expand All @@ -1438,6 +1478,8 @@ mixin ChangesNotifierHelperMixin {
}
}

/// Add a listener to the list of listeners.
/// - [listener] The listener to add.
@protected
void defaultAddListener(ChangeListener listener) {
assert(debugAssertNotDisposed(this));
Expand Down Expand Up @@ -1494,6 +1536,8 @@ mixin ChangesNotifierHelperMixin {
}
}

/// Remove a listener from the list of listeners.
/// - [listener] The listener to remove.
@protected
void defaultRemoveListener(ChangeListener listener) {
// This method is allowed to be called on disposed instances for usability
Expand Down Expand Up @@ -1521,6 +1565,8 @@ mixin ChangesNotifierHelperMixin {
}
}

/// Disposes the object making it unusable for further operations and
/// releasing the resources.
@mustCallSuper
void dispose() {
assert(debugAssertNotDisposed(this));
Expand All @@ -1541,6 +1587,8 @@ mixin ChangesNotifierHelperMixin {
_count = 0;
}

/// Notify all the listeners.
/// - [event] The event to send to the listeners.
@protected
@visibleForTesting
@pragma('vm:notify-debugger-on-exception')
Expand Down
14 changes: 14 additions & 0 deletions lib/src/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@ import 'package:flutter/foundation.dart';

import '../data_widget.dart';

/// A callback that receives a [ListChangeDetails] object.
typedef ListChangeListener<T> = void Function(ListChangeDetails<T> details);

/// A list that can be listened to for changes.
abstract class ListListenable<T> extends ValueListenable<List<T>> {
@override
List<T> get value;
void addChangeListener(ListChangeListener<T> listener);
void removeChangeListener(ListChangeListener<T> listener);
}

/// A list change details containing the added, removed, and index of the changes.
class ListChangeDetails<T> {
/// The added elements.
final Iterable<T> added;

/// The removed elements.
final Iterable<T> removed;

/// The index of the changes.
final int index;

/// Creates a list change details.
const ListChangeDetails(this.added, this.removed, this.index);
}

Expand All @@ -42,17 +51,22 @@ class _ListChangeListener<T> extends ChangeListener {
int get hashCode => listener.hashCode;
}

/// A list that can be listened to for changes and notifies listeners when the list changes.
class ListNotifier<T> extends ListListenable<T>
with ChangesNotifierHelperMixin, Iterable<T>
implements List<T> {
final List<T> _list;

/// Creates a list notifier.
ListNotifier([List<T> list = const []]) : _list = List<T>.from(list);

@override
List<T> get value => UnmodifiableListView<T>(_list);

/// Notifies listeners of the changes.
@protected
@visibleForOverriding
@pragma('vm:notify-debugger-on-exception')
void notifyListeners(ListChangeDetails<T> details) {
super.defaultNotifyListeners(details);
}
Expand Down
12 changes: 12 additions & 0 deletions lib/src/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ import 'package:flutter/foundation.dart';

import '../data_widget.dart';

/// A map change details containing the added and removed entries.
class MapChangeDetails<K, V> {
/// The added entries.
final Iterable<MapEntry<K, V>> added;

/// The removed entries.
final Iterable<MapEntry<K, V>> removed;

/// Creates a map change details.
const MapChangeDetails(this.added, this.removed);
}

/// A callback that receives a [MapChangeDetails] object.
typedef MapChangeListener<K, V> = void Function(MapChangeDetails<K, V> details);

/// A map that can be listened to for changes.
abstract class MapListenable<K, V> extends ValueListenable<Map<K, V>> {
@override
Map<K, V> get value;
Expand Down Expand Up @@ -40,17 +47,22 @@ class _MapChangeListener<K, V> extends ChangeListener {
int get hashCode => listener.hashCode;
}

/// A map that can be listened to for changes and notifies listeners when the map changes.
class MapNotifier<K, V> extends MapListenable<K, V>
with ChangesNotifierHelperMixin
implements Map<K, V> {
final Map<K, V> _map;

/// Creates a map notifier.
MapNotifier([Map<K, V> map = const {}]) : _map = Map<K, V>.from(map);

@override
Map<K, V> get value => UnmodifiableMapView<K, V>(_map);

/// Notifies listeners of the changes.
@protected
@visibleForOverriding
@pragma('vm:notify-debugger-on-exception')
void notifyListeners(MapChangeDetails<K, V> details) {
super.defaultNotifyListeners(details);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/src/notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,28 @@ extension ValueNotifierExtension<T> on ValueNotifier<T> {
return ValueNotifierUnmodifiableView(this);
}

/// Maps the value of the [ValueNotifier] to a new value.
ValueListenable<R> map<R>(R Function(T value) mapper) {
return MappedValueNotifier(this, mapper);
}
}

/// Extension on [ValueListenable] to provide a read-only view and mapping.
extension ValueListenableExtension<T> on ValueListenable<T> {
/// Returns a read-only view of the [ValueListenable].
ValueListenable<R> map<R>(R Function(T value) mapper) {
return MappedValueNotifier(this, mapper);
}
}

/// Extension on [ValueChangeNotifier] to provide a read-only view and mapping.
extension ValueChangeNotifierExtension<T> on ValueChangeNotifier<T> {
/// Returns a read-only view of the [ValueChangeNotifier].
ValueListenable<T> readOnly() {
return ValueNotifierUnmodifiableView(this);
}

/// Maps the value of the [ValueChangeNotifier] to a new value.
ValueListenable<R> map<R>(R Function(T value) mapper) {
return MappedValueNotifier(this, mapper);
}
Expand All @@ -68,10 +74,12 @@ class ValueNotifierUnmodifiableView<T> extends ValueListenable<T> {
}
}

/// A [ValueListenable] that maps the value of another [ValueListenable].
class MappedValueNotifier<T, R> extends ValueListenable<R> {
final ValueListenable<T> _notifier;
final R Function(T value) _mapper;

/// Constructs a [MappedValueNotifier] with the given [ValueListenable] and mapper function.
MappedValueNotifier(this._notifier, this._mapper);

@override
Expand Down
Loading

0 comments on commit 83cd8f4

Please sign in to comment.