Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observer component and MobX Hooks integration example app #27

Merged
merged 28 commits into from Aug 14, 2022
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8cbcaa3
ObserverComponent implementation in framework
juancastillo0 Aug 1, 2022
420641e
initial jaspr create mobx_hooks experiment
juancastillo0 Aug 1, 2022
49de82a
StatelessComponent and StatefulComponent based mobx_hooks implementation
juancastillo0 Aug 1, 2022
29ed126
implement mobx_hook logic with ObserverComponent
juancastillo0 Aug 1, 2022
23d9b05
implement extra hooks
juancastillo0 Aug 1, 2022
3ffd554
upgrade sdk to 2.17.0 in mobx_hooks experiment
juancastillo0 Aug 1, 2022
7f1ea2e
implement main ui using hooks and mobx observers
juancastillo0 Aug 1, 2022
412cc25
execute rebuild on ObserverElement.update
juancastillo0 Aug 3, 2022
1305b1f
clear _observerElements on unmount not in deactivate
juancastillo0 Aug 3, 2022
4d98e86
ObserverComponent test
juancastillo0 Aug 3, 2022
5e5bc5d
extract obs state model
juancastillo0 Aug 3, 2022
37b8bef
rename ctx -> globalHookContext, _startTracking -> startTracking
juancastillo0 Aug 3, 2022
34268d8
document hooks
juancastillo0 Aug 3, 2022
79ef2a1
mobx hooks test
juancastillo0 Aug 3, 2022
dd8316b
extract MobXHooksObserverComponent
juancastillo0 Aug 3, 2022
c1d320a
extract HookCtx state into a different class _HookCtxState
juancastillo0 Aug 3, 2022
1918077
add key and docs to MobXHooksObserverComponent
juancastillo0 Aug 4, 2022
8d86a3d
experimental HookCtxConfig with effects scheduler
juancastillo0 Aug 4, 2022
56b837c
add dispose return funciton to autorun
juancastillo0 Aug 4, 2022
c3bf811
useEffectSync, usePreviousDistinct and more hooks docs
juancastillo0 Aug 4, 2022
05c2513
use group for ComponentTester tests
juancastillo0 Aug 4, 2022
64fbbbf
add type constraint to ObserverElement's constructor
juancastillo0 Aug 4, 2022
22b2c5a
jaspr hooks test in example app
juancastillo0 Aug 5, 2022
2191c71
Merge remote-tracking branch 'upstream/develop' into observer_component
juancastillo0 Aug 8, 2022
263281b
add `&& _observerElements!.isNotEmpty` check before iterating
juancastillo0 Aug 8, 2022
e1ff368
update observer component tests for new renderer
juancastillo0 Aug 8, 2022
77ba3ad
use the ValueNotifier value in leaft node for observer component test
juancastillo0 Aug 8, 2022
40ef0bf
Merge remote-tracking branch 'upstream/develop' into observer_component
juancastillo0 Aug 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions experiments/mobx_hooks/.gitignore
@@ -0,0 +1,6 @@
# Files and directories created by pub.
.dart_tool/
.packages

# Conventional directory for build output.
build/
3 changes: 3 additions & 0 deletions experiments/mobx_hooks/CHANGELOG.md
@@ -0,0 +1,3 @@
## 1.0.0

- Initial version.
1 change: 1 addition & 0 deletions experiments/mobx_hooks/README.md
@@ -0,0 +1 @@
An absolute bare-bones web app.
30 changes: 30 additions & 0 deletions experiments/mobx_hooks/analysis_options.yaml
@@ -0,0 +1,30 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
153 changes: 153 additions & 0 deletions experiments/mobx_hooks/lib/app.dart
@@ -0,0 +1,153 @@
import 'dart:math';

import 'package:jaspr/jaspr.dart';

import 'mobx_hooks/hooks.dart';
import 'mobx_hooks/mobx_hooks.dart';

class App extends StatelessComponent {
const App({super.key});

@override
Iterable<Component> build(BuildContext context) sync* {
print('build App');
final text = useObs(() => 'initial');
final output = useObs(() => 0);
final seconds = useObs(() => 5);
final inputElement = useRef<dynamic>(() => null);

final reset = useCallback((_) {
text.value = 'initial';
seconds.value = 5;
if (inputElement.value != null) {
inputElement.value.value = text.value;
}
}, const []);

useAutorun(() {
final random = Random(text.value.hashCode);
final subs =
Stream.periodic(Duration(seconds: seconds.value)).listen((event) {
print('event seconds: ${seconds.value}, text: "${text.value}"');
output.value = random.nextInt(9000) + 1000;
});
return subs.cancel;
});

yield DomComponent(
tag: 'div',
styles: {
'display': 'flex',
'flex-direction': 'column',
'justify-content': 'center',
'align-items': 'flex-end',
'height': '100%',
'width': '270px',
'margin': 'auto',
},
children: [
DomComponent(
tag: 'div',
children: [
DomComponent(
tag: 'label',
styles: {'padding': '0 10px;'},
attributes: {'for': 'seed'},
child: Text('seed'),
),
DomComponent(
tag: 'input',
id: 'seed',
attributes: {'type': 'text', 'value': text.value},
events: {
'input': (event) {
inputElement.value = event.target;
text.value = inputElement.value.value;
}
},
),
],
),
DomComponent(tag: 'span', styles: {'height': '10px;'}),
SecondsInput(seconds: seconds),
DomComponent(
tag: 'button',
styles: {'margin': '10px 0;'},
events: {'click': reset},
child: Text('reset'),
),
OutputText(output: output),
],
);
}
}

class SecondsInput extends StatelessComponent {
const SecondsInput({super.key, required this.seconds});

final Obs<int> seconds;

@override
Iterable<Component> build(BuildContext context) sync* {
print('build SecondsInput');
final inputElement = useRef<dynamic>(() => null);

useAutorun(() {
final newValue = seconds.value.toString();
if (inputElement.value != null) {
inputElement.value.value = newValue;
}
return null;
});

yield DomComponent(
tag: 'div',
children: [
DomComponent(
tag: 'label',
styles: {'padding': '0 10px;'},
attributes: {'for': 'seconds'},
child: Text('seconds'),
),
DomComponent(
tag: 'input',
id: 'seconds',
attributes: {
'type': 'number',
'value': inputElement.value?.value ?? seconds.value.toString(),
},
events: {
'input': (event) {
inputElement.value = event.target;
final value = int.tryParse(event.target.value);
if (value != null && value > 0) {
seconds.value = value;
}
}
},
),
],
);
}
}

class OutputText extends StatelessComponent {
const OutputText({super.key, required this.output});

final Obs<int> output;

@override
Iterable<Component> build(BuildContext context) sync* {
print('build OutputText');
yield DomComponent(
tag: 'div',
children: [
DomComponent(
tag: 'h1',
styles: {'padding': '0 10px;', 'font-family': 'mono'},
child: Text('output: ${output.value}'),
),
],
);
}
}
7 changes: 7 additions & 0 deletions experiments/mobx_hooks/lib/main.dart
@@ -0,0 +1,7 @@
import 'package:jaspr/jaspr.dart';
import './app.dart';
import 'mobx_hooks/jaspr_observer.dart';

void main() {
runApp(const MobXHooksObserverComponent(child: App()));
}