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

Commit

Permalink
rename builder apis
Browse files Browse the repository at this point in the history
  • Loading branch information
aprosail committed May 20, 2024
2 parents c1046a1 + 0f34d0f commit ab39b77
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 32 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.7.0

- **Incompatible**: API about `ReContext` changed.
- Use `builder` instead of `ReContext`, which is conciser.
- Optimize tests and tidy code structure.

## 0.6.0

- Inherit data from widget tree ancestors.
Expand Down
26 changes: 19 additions & 7 deletions lib/src/context.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import 'package:flutter/widgets.dart';

extension WrapContext on Widget {
/// Same as wrapping current widget with a [Builder], which keeps chain style.
Widget wrap(Widget Function(BuildContext context, Widget child) builder) =>
ReContext((context) => builder(context, this));
Builder(builder: (context) => builder(context, this));
}

/// Refresh context, same as [Builder] but with conciser API.
class ReContext extends StatelessWidget {
const ReContext(this.builder, {super.key});
/// An encapsulation of [Builder], which makes it conciser.
Widget builder(Widget Function(BuildContext context) builder) =>
Builder(builder: builder);

final Widget Function(BuildContext context) builder;
extension WrapMedia on Widget {
Widget wrapMedia(MediaQueryData data) => MediaQuery(data: data, child: this);

@override
Widget build(BuildContext context) => builder(context);
/// Ensure the widget is wrapped by a [MediaQuery] ancestor.
///
/// Provide environment for [MediaQuery.of] that many widgets need,
/// including the [Text] widget. Without such ancestor,
/// once displaying a [Text],
/// it will throw exceptions.
Widget ensureMedia(BuildContext context) {
final media = MediaQuery.maybeOf(context);
return media == null
? wrapMedia(MediaQueryData.fromView(View.of(context)))
: this;
}
}
58 changes: 58 additions & 0 deletions lib/src/handler.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:flutter/widgets.dart';

import 'inherit.dart';

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

final T data;
final Widget child;

@override
State<InheritHandler<T>> createState() => _InheritHandlerState<T>();
}

class _InheritHandlerState<T> extends State<InheritHandler<T>> {
late var _data = widget.data;
T get data => _data;
set data(T value) {
if (_data != value) setState(() => _data = value);
}

@override
void didUpdateWidget(covariant InheritHandler<T> oldWidget) {
super.didUpdateWidget(oldWidget);
data = widget.data;
}

@override
Widget build(BuildContext context) => widget.child
.wrapInherit(_data)
.wrapInheritUnchanged(InheritHandlerCaller<T>(
updater: (data) => this.data = data,
));
}

class InheritHandlerCaller<T> {
const InheritHandlerCaller({required this.updater});

final void Function(T data) updater;
}

extension WrapHandler on Widget {
Widget wrapHandler<T>(T data) => InheritHandler<T>(data: data, child: this);
}

extension UpdateHandlerData on BuildContext {
void maybeUpdate<T>(T data) => find<InheritHandlerCaller<T>>()?.updater(data);

void updateAndTrust<T>(T data) =>
findAndTrust<InheritHandlerCaller<T>>().updater(data);

void updateAndCheck<T>(T data) =>
findAndCheck<InheritHandlerCaller<T>>().updater(data);
}
6 changes: 6 additions & 0 deletions lib/src/inherit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,10 @@ extension FindInherit on BuildContext {
assert(data != null, 'cannot find $T in context');
return data!;
}

T findAndCheck<T>() {
final data = find<T>();
if (data == null) throw Exception('cannot find $T in context');
return data;
}
}
18 changes: 0 additions & 18 deletions lib/src/media.dart

This file was deleted.

2 changes: 1 addition & 1 deletion lib/src/text.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/widgets.dart';

import 'media.dart';
import 'context.dart';

extension WrapDirectionality on Widget {
Widget wrapDirectionality(TextDirection direction) => Directionality(
Expand Down
2 changes: 1 addition & 1 deletion lib/wrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export 'src/align.dart';
export 'src/color.dart';
export 'src/context.dart';
export 'src/decorate.dart';
export 'src/handler.dart';
export 'src/inherit.dart';
export 'src/list.dart';
export 'src/media.dart';
export 'src/size.dart';
export 'src/text.dart';
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: wrap
description: Chain style programming syntax sugar utilities for flutter widgets.
version: 0.6.0
version: 0.7.0
repository: https://github.com/aprosail/wrap
environment: {sdk: ">=3.3.4 <4.0.0", flutter: ">=3.19.6"}
topics:
Expand Down
2 changes: 1 addition & 1 deletion test/context_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:wrap/wrap.dart';
void main() {
testWidgets('re context root', (t) async {
await t.pumpWidget(
ReContext((context) => const ColorProbe()
builder((context) => const ColorProbe()
.wrapForeground(context, foreground)
.ensureTextEnvironment(context)),
);
Expand Down
2 changes: 1 addition & 1 deletion test/inherit_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ void main() {
testWidgets('inherit and find', (t) async {
const message = 'it works';
await t.pumpWidget(
ReContext(
builder(
(context) => Text(context.findAndTrust<String>())
.wrapCenter
.ensureTextEnvironment(context),
Expand Down
4 changes: 2 additions & 2 deletions test/text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:wrap/wrap.dart';
void main() {
testWidgets('ensure text environment', (t) async {
const message = 'it works';
await t.pumpWidget(ReContext(
await t.pumpWidget(builder(
(context) => const Text(message).ensureTextEnvironment(context),
));
expect(find.text(message), findsOneWidget);
Expand All @@ -16,7 +16,7 @@ void main() {
const fontSize = 23.4;
const fontFamily = 'iosevka';
await t.pumpWidget(
ReContext((context) {
builder((context) {
final font = DefaultTextStyle.of(context).style;
return <Widget>[
'font color: ${font.color}'.textWidget,
Expand Down

0 comments on commit ab39b77

Please sign in to comment.