Skip to content

Commit

Permalink
Merge pull request #305 from schultek/feat/flutter-multiview
Browse files Browse the repository at this point in the history
Add flutter multi-view embedding support
  • Loading branch information
schultek authored Oct 4, 2024
2 parents 91a906f + 5a3e99d commit c36b175
Show file tree
Hide file tree
Showing 107 changed files with 2,114 additions and 289 deletions.
2 changes: 1 addition & 1 deletion docs/concepts/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void main() {
testComponents('renders my component', (tester) async {
// We want to test the MyComponent component.
// Assume this shows a count and a button to increase it.
await tester.pumpComponent(MyComponent());
tester.pumpComponent(MyComponent());
// Should render a [Text] component with content 'Count: 0'.
expect(find.text('Count: 0'), findsOneComponent);
Expand Down
2 changes: 1 addition & 1 deletion examples/flutter_embedding/lib/components/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

import 'effects_controls.dart';
import 'flutter_app_container.dart' if (dart.library.js_interop) 'flutter_app_container_web.dart';
import 'flutter_app_container.dart';
import 'interop_controls.dart';

@client
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

@Import.onWeb('package:flutter_riverpod/flutter_riverpod.dart', show: [#UncontrolledProviderScope])
@Import.onWeb('../widgets/app.dart', show: [#MyApp])
import 'flutter_app_container.imports.dart' as flt;
import 'flutter_target.dart';
import 'ripple_loader.dart';

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

@override
Iterable<Component> build(BuildContext context) sync* {
yield article([
div(id: 'flutter_target', [
RippleLoader(),
])
]);
yield FlutterTarget(
loader: RippleLoader(),
app: kIsWeb
? flt.UncontrolledProviderScope(
container: ProviderScope.containerOf(context),
child: flt.MyApp(),
)
: null,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// GENERATED FILE, DO NOT MODIFY
// Generated with jaspr_builder

export '../generated/imports/_web.dart' if (dart.library.io) '../generated/imports/_stubs.dart'
show UncontrolledProviderScope, UncontrolledProviderScopeOrStubbed, MyApp, MyAppOrStubbed;

This file was deleted.

8 changes: 5 additions & 3 deletions examples/flutter_embedding/lib/components/flutter_target.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import 'package:flutter/widgets.dart' show Widget;
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_flutter_embed/jaspr_flutter_embed.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

import '../providers/effects_provider.dart';
@Import.onWeb('package:flutter/widgets.dart', show: [#Widget])
import 'flutter_target.imports.dart';

class FlutterTarget extends StatelessComponent {
const FlutterTarget({required this.app, this.loader, super.key});

final Widget app;
final WidgetOrStubbed? app;
final Component? loader;

@override
Expand All @@ -20,6 +21,7 @@ class FlutterTarget extends StatelessComponent {

Component child = FlutterEmbedView(
key: GlobalObjectKey('flutter_target'),
id: "flutter_target",
classes: isHandheld ? 'handheld' : effects.join(' '),
styles: !isHandheld && rotation != 0
? Styles.box(
Expand All @@ -30,7 +32,7 @@ class FlutterTarget extends StatelessComponent {
)
: null,
loader: loader,
app: app,
widget: app,
);

if (isHandheld) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// GENERATED FILE, DO NOT MODIFY
// Generated with jaspr_builder

export '../generated/imports/_web.dart' if (dart.library.io) '../generated/imports/_stubs.dart'
show Widget, WidgetOrStubbed;
11 changes: 11 additions & 0 deletions examples/flutter_embedding/lib/generated/imports/_stubs.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// GENERATED FILE, DO NOT MODIFY
// Generated with jaspr_builder

// ignore_for_file: directives_ordering, non_constant_identifier_names

dynamic Widget;
typedef WidgetOrStubbed = dynamic;
dynamic UncontrolledProviderScope;
typedef UncontrolledProviderScopeOrStubbed = dynamic;
dynamic MyApp;
typedef MyAppOrStubbed = dynamic;
17 changes: 17 additions & 0 deletions examples/flutter_embedding/lib/generated/imports/_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// GENERATED FILE, DO NOT MODIFY
// Generated with jaspr_builder

// ignore_for_file: directives_ordering

import 'package:flutter/widgets.dart' show Widget;
import 'package:flutter_riverpod/flutter_riverpod.dart'
show UncontrolledProviderScope;
import '../../../widgets/app.dart' show MyApp;
export 'package:flutter/widgets.dart' show Widget;
export 'package:flutter_riverpod/flutter_riverpod.dart'
show UncontrolledProviderScope;
export '../../../widgets/app.dart' show MyApp;

typedef WidgetOrStubbed = Widget;
typedef UncontrolledProviderScopeOrStubbed = UncontrolledProviderScope;
typedef MyAppOrStubbed = MyApp;
2 changes: 2 additions & 0 deletions examples/flutter_embedding/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ void main() {

link(rel: 'manifest', href: 'manifest.json'),
link(rel: 'stylesheet', href: 'css/style.css', type: 'text/css'),

script(src: "flutter_bootstrap.js", async: true, []),
],
body: App(),
));
Expand Down
2 changes: 1 addition & 1 deletion examples/flutter_embedding/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ packages:
path: "../../modules/build/jaspr_web_compilers"
relative: true
source: path
version: "4.0.10"
version: "4.0.9"
js:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions examples/flutter_embedding/web/flutter_bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{flutter_js}}
{{flutter_build_config}}
46 changes: 46 additions & 0 deletions examples/flutter_multi_view/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Files and directories created by pub.
**/doc/api/
.dart_tool/
.packages

# Conventional directory for build output.
/build/

# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter related
.flutter-plugins
.flutter-plugins-dependencies
**/ios/Flutter/.last_build_id

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
15 changes: 15 additions & 0 deletions examples/flutter_multi_view/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# flutter_multi_view

A new jaspr project.

## Running the project

Run your project using `jaspr serve`.

The development server will be available on `http://localhost:8080`.

## Building the project

Build your project using `jaspr build`.

The output will be located inside the `build/jaspr/` directory.
38 changes: 38 additions & 0 deletions examples/flutter_multi_view/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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:flutter_lints/flutter.yaml

analyzer:
# Jaspr has a custom lint package 'jaspr_lints', which needs the 'custom_lint' analyzer plugin.
#
# Unfortunately, running 'dart analyze' does not pick up the custom lints. Instead, you need to
# run a separate command for this: `jaspr analyze`
plugins:
- custom_lint

# 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
86 changes: 86 additions & 0 deletions examples/flutter_multi_view/lib/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_flutter_embed/jaspr_flutter_embed.dart';

import 'components/counter.dart';
import 'constants/theme.dart';

@client
class App extends StatefulComponent {
const App({super.key});

@override
State<App> createState() => AppState();
}

class AppState extends State<App> with ViewTransitionMixin<App> {
List<String> counters = ['counter-1', 'counter-2'];

@override
void initState() {
super.initState();
FlutterEmbedView.preload();
}

void addCounter() async {
setStateWithViewTransition(() {
counters.add('targeted-counter');
}, postTransition: () {
counters[counters.length - 1] = 'counter-${counters.length}';
});
}

void removeCounter() {
setStateWithViewTransition(preTransition: () {
counters[counters.length - 1] = 'targeted-counter';
}, () {
counters.removeLast();
});
}

@override
Iterable<Component> build(BuildContext context) sync* {
yield div(classes: 'main', [
img(src: 'images/logo.png', width: 80),
div(classes: 'buttons', [
button(
onClick: () {
removeCounter();
},
[text('Less Counters')],
),
button(
onClick: () {
addCounter();
},
[text('More Counters')],
),
]),
div(classes: 'counters', [
for (var name in counters) Counter(name: name),
]),
]);
}

@css
static final styles = [
css('.main', [
css('&').flexbox(direction: FlexDirection.column, alignItems: AlignItems.center),
css('.buttons', [
css('&').flexbox(direction: FlexDirection.row),
css('button')
.box(padding: EdgeInsets.all(8.px), border: Border.all(BorderSide.solid(color: primaryColor, width: 1.px))),
css('button:first-child')
.box(radius: BorderRadius.horizontal(left: Radius.circular(6.px)), margin: EdgeInsets.only(right: (-1).px)),
css('button:last-child')
.box(radius: BorderRadius.horizontal(right: Radius.circular(6.px)), margin: EdgeInsets.only(left: (-1).px)),
]),
css('.counters', [
css('&').flexbox(
direction: FlexDirection.row,
wrap: FlexWrap.wrap,
justifyContent: JustifyContent.center,
),
]),
]),
];
}
Loading

0 comments on commit c36b175

Please sign in to comment.