Skip to content
This repository has been archived by the owner on Jun 30, 2024. It is now read-only.

Commit

Permalink
wrap inherit
Browse files Browse the repository at this point in the history
  • Loading branch information
aprosail committed May 19, 2024
2 parents 0ea55dc + caff723 commit c1046a1
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.6.0

- Inherit data from widget tree ancestors.
- Wrapper to handle data onto widget tree.
- Replace the old [Inherit](https://pub.dev/inherit) package.
- Apply [StrictLints](https://pub.dev/strict_lints) options.

## 0.5.2

- Fix bug about calling `setState` when `build`.
Expand Down
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include: package:flutter_lints/flutter.yaml
include: package:strict_lints/strict_lints.yaml
5 changes: 0 additions & 5 deletions example/test/widget_test.dart

This file was deleted.

61 changes: 61 additions & 0 deletions lib/src/inherit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:flutter/widgets.dart';

/// A wrap of generic on the [InheritedWidget] widget.
///
/// As it extends the [InheritedWidget] it can also
/// pass data to the descendants in the widget tree,
/// and let all related widget to re-renderer when the data changed.
/// But it let all similar inherit data to share the code
/// rather than inherit raw [InheritedWidget] once and once again.
class InheritedData<T> extends InheritedWidget {
/// Register an inherited [data] into the widget tree.
/// That all its descendants can access the [data]
/// by calling the [FindInherit.find] method (an extension on [BuildContext]).
///
/// It's more recommended to use [WrapInherit.wrapInherit]
/// (an extension on [Widget])
/// rather than calling this constructor directly.
const InheritedData({
super.key,
required this.data,
required super.child,
});

final T data;

@override
bool updateShouldNotify(covariant InheritedData<T> oldWidget) =>
this.data != oldWidget.data;
}

class InheritedUnchangedData<T> extends InheritedWidget {
const InheritedUnchangedData({
super.key,
required this.data,
required super.child,
});

final T data;

@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) => false;
}

extension WrapInherit on Widget {
Widget wrapInherit<T>(T data) => InheritedData<T>(data: data, child: this);

Widget wrapInheritUnchanged<T>(T data) =>
InheritedUnchangedData<T>(data: data, child: this);
}

extension FindInherit on BuildContext {
T? find<T>() => dependOnInheritedWidgetOfExactType<InheritedData<T>>()?.data;

T findAndDefault<T>(T defaultValue) => find<T>() ?? defaultValue;

T findAndTrust<T>() {
final data = find<T>();
assert(data != null, 'cannot find $T in context');
return data!;
}
}
34 changes: 18 additions & 16 deletions lib/src/size.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ extension WrapSize on Widget {
/// the size is based on the context of this widget,
/// so that the inner size change listener should be close to
/// where the context is build, or there might be potential conflicts.
Widget listenSizeChange(State state, void Function(Size size) listener) {
return NotificationListener(
onNotification: (notification) {
if (notification is SizeChangedLayoutNotification) {
final context = state.context;
listener(context.size ?? MediaQuery.of(context).size);
WidgetsBinding.instance.addPostFrameCallback(
// ignore: invalid_use_of_protected_member
(timestamp) => state.setState(() {}),
);
Widget listenSizeChange(State state, void Function(Size size) listener) =>
NotificationListener(
onNotification: (notification) {
if (notification is! SizeChangedLayoutNotification) return false;
state.resolveSizeChange(listener);
return true;
}
return false;
},
child: SizeChangedLayoutNotifier(child: this),
);
}
},
child: SizeChangedLayoutNotifier(child: this),
);

Widget wrapPadding(EdgeInsets padding) =>
Padding(padding: padding, child: this);
}

extension _ResolveSizeChange on State {
void resolveSizeChange(void Function(Size size) listener) {
listener(context.size ?? MediaQuery.of(context).size);
WidgetsBinding.instance.addPostFrameCallback(
// ignore: invalid_use_of_protected_member
(timestamp) => setState(() {}),
);
}
}
3 changes: 2 additions & 1 deletion lib/src/text.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/widgets.dart';
import 'package:wrap/wrap.dart';

import 'media.dart';

extension WrapDirectionality on Widget {
Widget wrapDirectionality(TextDirection direction) => Directionality(
Expand Down
1 change: 1 addition & 0 deletions lib/wrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export 'src/align.dart';
export 'src/color.dart';
export 'src/context.dart';
export 'src/decorate.dart';
export 'src/inherit.dart';
export 'src/list.dart';
export 'src/media.dart';
export 'src/size.dart';
Expand Down
8 changes: 4 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: wrap
description: Chain style programming syntax sugar utilities for flutter widgets.
version: 0.5.2
version: 0.6.0
repository: https://github.com/aprosail/wrap
environment: {sdk: ">=3.3.4 <4.0.0", flutter: ">=3.19.6"}
topics:
- syntax-sugar
- code-style
- chain-style
- chain-programming
- chain-style-programming
- flutter-widgets
- flutter-data-inherit

dependencies:
flutter: {sdk: flutter}

dev_dependencies:
flutter_test: {sdk: flutter}
flutter_lints: ^3.0.0
strict_lints: ^0.1.1
17 changes: 17 additions & 0 deletions test/inherit_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wrap/wrap.dart';

void main() {
testWidgets('inherit and find', (t) async {
const message = 'it works';
await t.pumpWidget(
ReContext(
(context) => Text(context.findAndTrust<String>())
.wrapCenter
.ensureTextEnvironment(context),
).wrapInherit(message),
);
expect(find.text(message), findsOneWidget);
});
}

0 comments on commit c1046a1

Please sign in to comment.