Allow nesting classes in render

This commit is contained in:
Tobe O 2019-03-23 18:02:57 -04:00
parent 958b918ad2
commit 37aad85e5f
5 changed files with 75 additions and 7 deletions

View file

@ -14,7 +14,7 @@ class _AppState {
} }
} }
@Dsx(template: '<div>Tick count: {state.ticks}</div>') @Jael(template: '<div>Tick count: {{state.ticks}}</div>')
class StatefulApp extends Component<_AppState> with _StatefulAppJaelTemplate { class StatefulApp extends Component<_AppState> with _StatefulAppJaelTemplate {
Timer _timer; Timer _timer;

View file

@ -0,0 +1,25 @@
import 'package:jael_web/jael_web.dart';
part 'using_components.g.dart';
@Jael(template: '''
<div>
<h1>Welcome to my app</h1>
<LabeledInput name="username" />
</div>
''')
class MyApp extends Component with _MyAppJaelTemplate {}
@Jael(template: '''
<div>
<label>
<b>{{name}}:</b>
</label>
<br>
<input name=name placeholder="Enter " + name + "..." type="text">
</div>
''')
class LabeledInput extends Component with _LabeledInputJaelTemplate {
final String name;
LabeledInput({this.name});
}

View file

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'using_components.dart';
// **************************************************************************
// JaelComponentGenerator
// **************************************************************************
abstract class _MyAppJaelTemplate implements Component<dynamic> {
@override
DomNode render() {
return h('div', {}, [
h('h1', {}, [text('Welcome to my app')]),
LabeledInput(name: "username")
]);
}
}
abstract class _LabeledInputJaelTemplate implements Component<dynamic> {
String get name;
@override
DomNode render() {
return h('div', {}, [
h('label', {}, [
h('b', {}, [text(name.toString()), text(':')])
]),
h('br', {}, []),
h('input', {
'name': name,
'placeholder': "Enter " + name + "...",
'type': "text"
}, [])
]);
}
}

View file

@ -9,6 +9,8 @@ import 'package:path/path.dart' as p;
import 'package:source_gen/source_gen.dart'; import 'package:source_gen/source_gen.dart';
import 'util.dart'; import 'util.dart';
var _upper = RegExp(r'^[A-Z]');
Builder jaelComponentBuilder(_) { Builder jaelComponentBuilder(_) {
return SharedPartBuilder([JaelComponentGenerator()], 'jael_web_cmp'); return SharedPartBuilder([JaelComponentGenerator()], 'jael_web_cmp');
} }
@ -124,11 +126,17 @@ class JaelComponentGenerator extends GeneratorForAnnotation<Jael> {
: CodeExpression(Code(attr.value.span.text)); : CodeExpression(Code(attr.value.span.text));
} }
var tagName = child.tagName.name;
if (!_upper.hasMatch(tagName)) {
return refer('h').call([ return refer('h').call([
literalString(child.tagName.name), literalString(tagName),
literalMap(attrs), literalMap(attrs),
literalList(child.children.map(compileElementChild)), literalList(child.children.map(compileElementChild)),
]); ]);
} else {
// TODO: How to pass children?
return refer(tagName).newInstance([], attrs);
}
// return refer(child.tagName.name).newInstance([]); // return refer(child.tagName.name).newInstance([]);
} else { } else {
throw 'Unsupported: $child'; throw 'Unsupported: $child';

View file

@ -1,6 +1,6 @@
import 'dom_node.dart'; import 'dom_node.dart';
abstract class Component<State> { abstract class Component<State> extends DomNode {
State state; State state;
DomNode render(); DomNode render();