Skip to content

Commit

Permalink
add lazy tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kealjones-wk committed Sep 12, 2024
1 parent f5605c2 commit 131ceb9
Show file tree
Hide file tree
Showing 7 changed files with 1,338 additions and 159 deletions.
67 changes: 50 additions & 17 deletions example/suspense/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,56 @@

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta charset="utf-8">
<title>over_react Suspense example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta charset="utf-8" />
<title>over_react Suspense example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

<!-- javascript -->
<!-- javascript -->
</head>
<body>
<div id="content"></div>

</head>
<body>
<div id="content"></div>

<script src="packages/react/react_prod.js"></script>
<script src="packages/react/react_dom_prod.js"></script>

<script type="application/javascript" defer src="main.dart.js"></script>
</body>
<script src="packages/react/react_prod.js"></script>
<script src="packages/react/react_dom_prod.js"></script>
<script>
const defaultMessageContext = React.createContext('default context value');
window.TestJsComponent = React.forwardRef(function (props, ref) {
const {
buttonProps = {},
listOfProps = [],
inputRef,
buttonComponent = 'button',
inputComponent = 'input',
component = 'span',
children,
messageContext = defaultMessageContext,
...rest
} = props;
let message = React.useContext(messageContext);
if (typeof message !== 'string') {
// Work around react-dart always wrapping values in an object (FED-467)
// whose value is under a property `Symbol('react-dart.context')`.
// Since it's a local symbol, we can't construct a matching symbol, so we find the matching one.
const symbol = Object.getOwnPropertySymbols(message).find((s) =>
s.description.includes('react-dart.context')
);
message = message[symbol];
}
return React.createElement(
'div',
{},
React.createElement(buttonComponent, buttonProps),
React.createElement('li', listOfProps[0]),
React.createElement(inputComponent, { type: 'text', ref: inputRef }),
React.createElement(component, { ...rest, ref }, children),
React.createElement('div', { role: 'alert' }, message)
);
});
</script>
<script type="application/javascript" defer src="main.dart.js"></script>
</body>
</html>
51 changes: 50 additions & 1 deletion example/suspense/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,60 @@

import 'dart:html';

import 'package:js/js.dart';
import 'package:over_react/js_component.dart';
import 'package:over_react/over_react.dart';
import 'package:react/react_client/component_factory.dart';
import 'package:react/react_client/react_interop.dart' hide lazy;
import 'package:react/react_dom.dart' as react_dom;
import 'counter_component.dart' deferred as lazy_component;
import 'third_party_file.dart';

part 'main.over_react.g.dart';

@Props(keyNamespace: '')
mixin TestJsProps on UiProps {
@Accessor(key: 'buttonProps')
JsMap? _$raw$buttonProps;

Map? get buttonProps => unjsifyMapProp(_$raw$buttonProps);
set buttonProps(Map? value) => _$raw$buttonProps = jsifyMapProp(value);

@Accessor(key: 'listOfProps')
List<dynamic>? _$raw$listOfProps;

List<Map?>? get listOfProps => unjsifyMapListProp(_$raw$listOfProps);
set listOfProps(List<Map?>? value) => _$raw$listOfProps = jsifyMapListProp(value);

@Accessor(key: 'inputRef')
dynamic _$raw$inputRef;

dynamic get inputRef => unjsifyRefProp(_$raw$inputRef);
set inputRef(dynamic value) => _$raw$inputRef = jsifyRefProp(value);

@Accessor(key: 'messageContext')
ReactContext? _$raw$messageContext;

Context<String?>? get messageContext => unjsifyContextProp(_$raw$messageContext);
set messageContext(Context<String?>? value) => _$raw$messageContext = jsifyContextProp(value);

dynamic /*ElementType*/ component;
dynamic /*ElementType*/ inputComponent;
dynamic /*ElementType*/ buttonComponent;
}

@JS('TestJsComponent')
external ReactClass get _TestJs;

UiFactory<TestJsProps> TestJs = uiJsComponent(
ReactJsComponentFactoryProxy(_TestJs),
_$TestJsConfig, // ignore: undefined_identifier
);

UiFactory<TestJsProps> LazyTestJs = lazy(() async => TestJs,
_$TestJsConfig, // ignore: undefined_identifier
);

UiFactory<CounterPropsMixin> LazyCounter = lazy(() async {
await Future.delayed(Duration(seconds: 5));
await lazy_component.loadLibrary();
Expand All @@ -37,7 +86,7 @@ void main() {
'I am a fallback UI that will show while we load the lazy component! The load time is artificially inflated to last an additional 5 seconds just to prove it\'s working!',
)
)(
(LazyCounter()..initialCount = 2)(
(LazyTestJs())(
(Dom.div()..id = 'Heyyy!')(),
),
),
Expand Down
45 changes: 23 additions & 22 deletions lib/src/util/lazy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@

library over_react.lazy;

import 'dart:html';

import 'package:over_react/over_react.dart';
import 'package:react/react.dart' as react;

UiFactory<TProps> lazy<TProps extends UiProps>(Future<UiFactory<TProps>> Function() loadComponent,/* UiFactoryConfig<TProps> */ dynamic _config) {
UiFactory<TProps> lazy<TProps extends UiProps>(Future<UiFactory<TProps>> Function() loadComponent,/* UiFactoryConfig<TProps> */ dynamic _config, {bool useJsFactoryProxy = false}) {
ArgumentError.checkNotNull(_config, '_config');

if (_config is! UiFactoryConfig<TProps>) {
Expand All @@ -26,34 +28,33 @@ UiFactory<TProps> lazy<TProps extends UiProps>(Future<UiFactory<TProps>> Functio
r'using either the generated factory config (i.e. _$FooConfig) or manually '
'declaring your config correctly.');
}

final lazyFactoryProxy = react.lazy(() async {
final factory = await loadComponent();
final wrapper = uiForwardRef<TProps>(
(props, ref) {
final builder = factory()
..addProps(props)
..ref = ref;
return props.children == null || (props.children != null && props.children?.isEmpty != false) ? builder() : builder(props.children);
},
UiFactoryConfig(
propsFactory: PropsFactory.fromUiFactory(factory),
displayName: 'Lazy${_config.displayName}',
),
);
return wrapper().componentFactory!;
// return factory().componentFactory!;
});

// ignore: invalid_use_of_protected_member
// ignore: invalid_use_of_protected_member
final propsFactory = _config.propsFactory;
ArgumentError.checkNotNull(propsFactory, '_config.propsFactory');
propsFactory!;


final lazyFactoryProxy = react.lazy(() async {
final factory = await loadComponent();
// final wrapper = uiForwardRef<TProps>(
// (props, ref) {
// final builder = factory()
// ..addProps(props)
// ..ref = ref;
// return props.children == null || (props.children != null && props.children?.isEmpty != false) ? builder() : builder(props.children);
// },
// UiFactoryConfig(
// propsFactory: PropsFactory.fromUiFactory(factory),
// displayName: 'Lazy${_config.displayName}',
// ),
// );
// return wrapper().componentFactory!;
return factory().componentFactory!;
}, useJsFactoryProxy: useJsFactoryProxy);

TProps _uiFactory([Map? props]) {
TProps builder;
if (props == null) {
// propsFactory should get promoted to non-nullable here, but it does not some reason propsF
builder = propsFactory.jsMap(JsBackedMap());
} else if (props is JsBackedMap) {
builder = propsFactory.jsMap(props);
Expand Down
Loading

0 comments on commit 131ceb9

Please sign in to comment.