mvcoconut / coconut.ui Goto Github PK
View Code? Open in Web Editor NEWWow, such reactive view! Much awesome!
License: The Unlicense
Wow, such reactive view! Much awesome!
License: The Unlicense
Right now if you have a coconut view then it's impossible to have default children, and you always have to specify it. If you create View classes that are used as containers many times it would be convinient to just define the children directly.
ie using hxx:
<List>
<ListItem>hello1</ListItem>
<ListItem>hello2</ListItem>
<ListItem>hello3</ListItem>
</List>
From discord:
I have a Array<Array> which worked fine as @:computed, but now I tried to clean the stuff up and made a new component. Then I want to pass that computed array to the component, so I have to convert that to a pure list. Would be nice if this could keep working.
As it's been asked before thought I'd add it for discussion. Not sure what it would look like in coconut terms. Or if it should interop with React's implementation when using coconut.react-core
.
I think this one is about tink_hxx, but I am not sure
import coconut.Ui.*;
import coconut.ui.*;
import coconut.data.*;
class Main {
static function main() {
hxx('<Dropdown values=${List.fromArray([{name:'a'}, {name:'b'}])} />');
}
}
class Dropdown extends View<{values:List<Value>}> {
function render() '<div/>';
}
typedef Value = {
var name(default, never):String;
}
Error:
/Users/kevin/Codes/test/src/Main.hx:9: characters 67-68 : Unexpected b
If main()
is
static function main() {
var list = List.fromArray([{name:'a'}, {name:'b'}]);
hxx('<Dropdown values=${List.fromArray([{name:'a'}, {name:'b'}])} />');
}
Error becomes:
/Users/kevin/Codes/test/src/Main.hx:9: characters 67-68 : Unexpected b
/Users/kevin/Codes/test/src/Main.hx:9: characters 67-68 : Missing ;
/Users/kevin/Codes/test/src/Main.hx:9: characters 68-77 : Missing ;
/Users/kevin/Codes/test/src/Main.hx:9: characters 77-78 : Unexpected )
It compiles if the List is stored in a variable before hxx()
;
So instead of {current:T}
it is State<T>
so in viewDidMount
we can write:
var binding = ref.bind(null, div -> doSomething(div));
untilUnmounted(binding.dissolve);
otherwise with the current implementation we need to handle both viewDidMount
and viewDidUpdate
? Or did I miss something?
I used to have something like this, that worked before the last change 2922be9
class MyButton extends View {
@:attribute var title: String;
@:attribute var click: Void->Void;
@:attribute var child: Void->RenderResult = emptyChild;
function emptyChild()
return <span></span>;
function render() {
return
<a href="#"
class="button button-outline"
onclick={click}
>{title}
{child()}
</a>;
}
}
now I get an error "TypeError: tink_state_Observable.get_value(...) is not a function" in:
,child: function() {
return (tink_state_Observable.get_value(this.__coco_child))();
}
looks like __coco_child
is initialized with something weird
This one works quite fine: https://try.haxe.org/#2D0Bb
Many times when I generate an error in a view class that inherits the properties of a big object I receive such error messages:
Error: (<js.html.Event, js.html.InputElement>>>, ?ongotpointercapture) Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfullscreenerror : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfullscreenchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfocus : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onerror : Null<tink.Callback<vdom.EventFrom<js.html.ErrorEvent, js.html.InputElement>>>, ?onended : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onemptied : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondurationchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondrop : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragstart : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragover : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragleave : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragenter : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragend : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondrag : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondblclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?oncut : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncopy : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncontextmenu : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplaythrough : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onblur : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onabort : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?name : Null<Null<String>>, ?min : Null<Null<String>>, ?maxlength : Null<Int>, ?max : Null<Null<String>>, ?lang : Null<Null<String>>, ?label : Null<Null<String>>, ?key : Null<Null<vdom.Key>>, ?id : Null<Null<String>>, ?icon : Null<Null<String>>, ?hidden : Null<Bool>, ?draggable : Null<Bool>, ?disabled : Null<Bool>, ?dir : Null<Null<String>>, ?dense : Null<Bool>, ?contentEditable : Null<Bool>, ?compact2 : Null<Bool>, ?className : Null<Null<vdom.ClassName>>, ?checked : Null<Bool>, ?attributes : Null<Null<vdom.PureDynamicAccess<vdom.Ext>>>, ?accessKeyLabel : Null<Null<String>>, ?accessKey : Null<Null<String>> } should be mdc.ButtonAttr
Error: (putElement>>>, ?onfullscreenerror) Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfullscreenchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfocus : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onerror : Null<tink.Callback<vdom.EventFrom<js.html.ErrorEvent, js.html.InputElement>>>, ?onended : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onemptied : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondurationchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondrop : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragstart : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragover : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragleave : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragenter : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragend : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondrag : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondblclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?oncut : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncopy : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncontextmenu : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplaythrough : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onblur : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onabort : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?name : Null<Null<String>>, ?min : Null<Null<String>>, ?maxlength : Null<Int>, ?max : Null<Null<String>>, ?lang : Null<Null<String>>, ?label : Null<Null<String>>, ?key : Null<Null<vdom.Key>>, ?id : Null<Null<String>>, ?icon : Null<Null<String>>, ?hidden : Null<Bool>, ?draggable : Null<Bool>, ?disabled : Null<Bool>, ?dir : Null<Null<String>>, ?dense : Null<Bool>, ?contentEditable : Null<Bool>, ?compact2 : Null<Bool>, ?className : Null<Null<vdom.ClassName>>, ?checked : Null<Bool>, ?attributes : Null<Null<vdom.PureDynamicAccess<vdom.Ext>>>, ?accessKeyLabel : Null<Null<String>>, ?accessKey : Null<Null<String>> } should be { ?value : Null<String>, ?unelevated : Null<Bool>, ?type : Null<String>, ?title : Null<String>, ?tabIndex : Null<Int>, ?style : Null<vdom.Style>, ?stroked : Null<Bool>, ?step : Null<String>, ?spellcheck : Null<Bool>, ?ripple : Null<Bool>, ?required : Null<Bool>, ?raised : Null<Bool>, ?placeholder : Null<String>, ?onwheel : Null<tink.Callback<vdom.EventFrom<js.html.WheelEvent, js.html.InputElement>>>, ?onwaiting : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onvolumechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ontouchstart : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchmove : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchend : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchcancel : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontimeupdate : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsuspend : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsubmit : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onstalled : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onshow : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onselect : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeking : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeked : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onscroll : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onresize : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onreset : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onratechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onprogress : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerup : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerover : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerout : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointermove : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerlockerror : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerlockchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerleave : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerenter : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerdown : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointercancel : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onplaying : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpause : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpaste : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?onmouseup : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseover : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseout : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousemove : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseleave : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseenter : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousedown : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onlostpointercapture : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadstart : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadedmetadata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadeddata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onload : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onkeyup : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeypress : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeydown : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?oninvalid : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oninput : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ongotpointercapture : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfullscreenerror : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfullscreenchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onfocus : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onerror : Null<tink.Ca
Error: (llback<vdom.EventFrom<js.html.ErrorEvent, js.html.InputElement>>>, ?onended) Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onemptied : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondurationchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ondrop : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragstart : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragover : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragleave : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragenter : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondragend : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondrag : Null<tink.Callback<vdom.EventFrom<js.html.DragEvent, js.html.InputElement>>>, ?ondblclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?oncut : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncopy : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?oncontextmenu : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onclick : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplaythrough : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oncanplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onblur : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onabort : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?name : Null<String>, ?min : Null<String>, ?maxlength : Null<Int>, ?max : Null<String>, ?lang : Null<String>, ?label : Null<String>, ?key : Null<vdom.Key>, ?id : Null<String>, ?icon : Null<String>, ?hidden : Null<Bool>, ?draggable : Null<Bool>, ?disabled : Null<Bool>, ?dir : Null<String>, ?dense : Null<Bool>, ?contentEditable : Null<Bool>, ?compact2 : Null<Bool>, ?className : Null<vdom.ClassName>, ?checked : Null<Bool>, ?attributes : Null<vdom.PureDynamicAccess<vdom.Ext>>, ?accessKeyLabel : Null<String>, ?accessKey : Null<String> }
Information:No additional error information available.
Error: (Command exited with an error code) 1
C:\Users\grosmar\AppData\Roaming\haxe\haxe_libraries\coconut.ui\0.6.1\haxelib\src\coconut\ui\macros\ViewBuilder.hx
Error:(127, 79) { ?value : Null<Null<String>>, ?unelevated : Null<Bool>, ?type : Null<Null<String>>, ?title : Null<Null<String>>, ?tabIndex : Null<Int>, ?style : Null<Null<vdom.Style>>, ?stroked : Null<Bool>, ?step : Null<Null<String>>, ?spellcheck : Null<Bool>, ?ripple : Null<Bool>, ?required : Null<Bool>, ?raised : Null<Bool>, ?placeholder : Null<Null<String>>, ?onwheel : Null<tink.Callback<vdom.EventFrom<js.html.WheelEvent, js.html.InputElement>>>, ?onwaiting : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onvolumechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ontouchstart : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchmove : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchend : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchcancel : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontimeupdate : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsuspend : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsubmit : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onstalled : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onshow : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onselect : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeking : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeked : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onscroll : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onresize : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onreset : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onratechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onprogress : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerup : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerover : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerout : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointermove : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerlockerror : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerlockchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerleave : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerenter : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerdown : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointercancel : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onplaying : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpause : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpaste : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?onmouseup : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseover : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseout : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousemove : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseleave : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseenter : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousedown : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onlostpointercapture : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadstart : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadedmetadata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadeddata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onload : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onkeyup : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeypress : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeydown : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?oninvalid : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oninput : Null<tink.Callback<vdom.EventFrom
Error:(127, 79) { ?value : Null<Null<String>>, ?unelevated : Null<Bool>, ?type : Null<Null<String>>, ?title : Null<Null<String>>, ?tabIndex : Null<Int>, ?style : Null<Null<vdom.Style>>, ?stroked : Null<Bool>, ?step : Null<Null<String>>, ?spellcheck : Null<Bool>, ?ripple : Null<Bool>, ?required : Null<Bool>, ?raised : Null<Bool>, ?placeholder : Null<Null<String>>, ?onwheel : Null<tink.Callback<vdom.EventFrom<js.html.WheelEvent, js.html.InputElement>>>, ?onwaiting : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onvolumechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ontouchstart : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchmove : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchend : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontouchcancel : Null<tink.Callback<vdom.EventFrom<js.html.TouchEvent, js.html.InputElement>>>, ?ontimeupdate : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsuspend : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onsubmit : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onstalled : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onshow : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onselect : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeking : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onseeked : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onscroll : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onresize : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onreset : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onratechange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onprogress : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerup : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerover : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerout : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointermove : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerlockerror : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerlockchange : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpointerleave : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerenter : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointerdown : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onpointercancel : Null<tink.Callback<vdom.EventFrom<js.html.PointerEvent, js.html.InputElement>>>, ?onplaying : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onplay : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpause : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onpaste : Null<tink.Callback<vdom.EventFrom<js.html.ClipboardEvent, js.html.InputElement>>>, ?onmouseup : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseover : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseout : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousemove : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseleave : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmouseenter : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onmousedown : Null<tink.Callback<vdom.EventFrom<js.html.MouseEvent, js.html.InputElement>>>, ?onlostpointercapture : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadstart : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadedmetadata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onloadeddata : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onload : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?onkeyup : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeypress : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?onkeydown : Null<tink.Callback<vdom.EventFrom<js.html.KeyboardEvent, js.html.InputElement>>>, ?oninvalid : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?oninput : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.InputElement>>>, ?ongotpointercapture : Null<tink.Callback<vdom.EventFrom<js.html.Event, js.html.In
Error:(127, 79) Inconsistent setter for field compact2 : never should be default
Error:(127, 79) For function argument 'attr'
D:\GIT-REPOS\coconut.mdc\src\mdc\Button.hx
Error:(9, -1) Defined in this class
Finding the error in it is kind of hell. I guess it's coming from the nature of the compiler.
My proposal is a big change, but what if the View class signature would look like this:
class View<{attr:T, ?children:T}> extends BaseView ...
It would make the types readable in case of error also, and it would make place for default children too.
What do you think?
When pasting your first sample from the doc it triggers:
coconut,ui/0,9,0/src/coconut/ui/macros/Generator.hx:63: characters 55-64 : Type not found : TagCreate
I don't know if there's some magic under the hood but TagCreate
in Generator.hx
is imported with import tink.hxx.Generator.TagCreate;
and doesn't seem to exist in that file (unless built from macro !?).
TagCreate
exists in tink.hxx.Generator.Tag
though, but importing it spawn different errors.
I'm using haxe4-rc1
class Main extends coconut.ui.View {
@:attr var foo:String->Void;
static function main() {}
function render() '<div/>';
static function getDerivedStateFromAttributes(attrs) return {}
}
gives: Explicit type required for field foo
Doesn't work:
@:optional @:attribute var foo:Foo;
Works:
@:attribute var foo:Foo = null;
We ran into a view that had:
class Blub extends View {
@:attribute var foo:Bool;
function render() '
<if {foo}><button>click me</button></if>
';
}
This can become problematic in many cases, for example when calling toElement
to mount it into DOM, but receiving null
. Simplest solution would be to disallow for views to return nothing - could be achieved in hxx.
If an attribute changes that is a Callback
(or a function returning Void
), it's not necessary to invalidate the view. However, proper storage and propagation will be slightly tricky:
class Container extends View {
@:attribute var onclick:Void->Void;
function render() '
<Button onclick={onclick} />
';
}
If onclick
changes in the Container
, then it should also change in the child Button
. One way to achieve this would be to wrap callback attributes in something like this:
abstract Action<T>(Void->T) {
public function get():T return this();
@:from macro static function ofAny<T>(e:ExprOf<T>):ExprOf<Action<T>>;
}
This is similar to coconut.data.Value
, except that it provides just indirection without the overhead of observability.
class Main {
static function main() {}
}
class MyView<T:EnumValue> extends coconut.ui.View {
@:attr var data:Data<T>;
function render() return null;
}
class Data<T:EnumValue> implements coconut.data.Model {}
This gives Type not found : T
Commenting out the attribute results in Invalid number of type parameters for MyView
Hi
Sorry if it already was discussed, but I did not find anything related.
Looks like currently coconut.ui not supporting Haxe's new null safety feature.
Is there any plans to support it?
Thank you
So I have been working on an imitation of vdom.VDom, the repository is here xdom, it depends on Haxe's Xml library, instead of javascript DOM library.
Although their implementations are different, I followed the tests in tink.hxx to craft mine, but I don't know how to go about making it compatible with coconut.ui.
This is what the generator code looks like:
package xdom;
import haxe.DynamicAccess;
import haxe.macro.Expr;
using tink.hxx.Node;
import tink.hxx.Located;
using tink.hxx.Attribute;
#if macro
class Dom extends tink.hxx.Generator {
var __root:Expr;
public function new(e) {
super();
this.__root = e;
}
var childrenType = haxe.macro.ComplexTypeTools.toType(macro:Dynamic);
override function node(n:tink.hxx.Node, pos:haxe.macro.Expr.Position) {
var attr:Array<tink.anon.Macro.Part> = [], splats = [];
for (a in n.attributes)
switch a {
case Splat(e):
splats.push(e);
case Empty(name):
attr.push({
name: name.value,
pos: name.pos,
getValue: function(_) return macro @:pos(name.pos) true,
});
case Regular(name, value):
attr.push({
name: name.value,
pos: name.pos,
getValue: function(_) return value,
});
}
var a = tink.anon.Macro.mergeParts(attr, splats, pos, macro:Dynamic);
var children = switch n.children {
case null | {value: null | []}: macro null;
case v: {
makeChildren(v, childrenType, false);
}
}
return macro @:pos(pos) Root.tag($__root, $v{n.name.value}, $a, $children);
}
}
#end
The DOM representation:
package xdom;
import haxe.macro.Expr;
abstract Root(Xml) from Xml to Xml {
public inline function new(?name:String) {
if (name != null) {
this = Xml.createElement(name);
} else {
this = Xml.createElement('root');
}
}
static public function tag(?root:Root, name:String, attr:Dynamic, ?children:Array<Dynamic>):Dynamic {
if (root == null) {
root = Xml.createElement(name);
for (a in Reflect.fields(attr)) {
root.set(a, Reflect.field(attr, a));
}
if (children != null)
for (child in children) {
root.addChild(child);
}
return root;
} else {
var child = Xml.createElement(name);
for (a in Reflect.fields(attr)) {
child.set(a, Reflect.field(attr, a));
}
if (children != null)
for (_child in children) {
if(Std.is(_child, Xml)){
child.addChild(_child);
} else {
child.addChild(Xml.createPCData(_child));
}
}
root.addChild(child);
return child;
}
}
.......
macro public function update(ethis, e) {
return new Dom(ethis).root(tink.hxx.Parser.parseRoot(e, {
defaultExtension: 'hxx',
isVoid: function(s) return switch s.value {
case 'img': true;
default: false;
}
}));
}
}
haxe 4p3
import coconut.ui.*;
import coconut.Ui.*;
import js.Browser.*;
class Main extends View {
static function main() {
Renderer.mount(document.body, hxx('<Main/>'));
}
@:attr var foo:Int = 0;
@:computed var bar:Int = foo + 1;
function render() {
trace('render');
return @hxx '
<div>${foo} ${bar}</div>
';
}
}
Generated the following code:
var Main = function(__coco_data_) {
this.bar = tink_state__$Observable_Observable_$Impl_$.get_value(this.__slots.foo) + 1;
this.__tink_defaults0 = { foo : tink_state__$Observable_Observable_$Impl_$["const"](0)};
this.__slots = { foo : new coconut_ui_tools_Slot(this,null)};
this.__initAttributes(__coco_data_);
coconut_ui_View.call(this,$bind(this,this.render),null,null,null,null,null);
};
and this.__slots.foo
is still undefined at the first line
Running mostly github versions of everything, I get Cannot read property '__coco_i' of undefined
in RowView.render
.
class Main {
public static function main() {
var data = new Data();
coconut.ui.Renderer.mount(
cast js.Browser.document.body.appendChild(js.Browser.document.createDivElement()),
coconut.Ui.hxx('
<div><for {item in data.rows}>
<RowView row={item} />
</for></div>')
);
haxe.Timer.delay(function() data.rows.splice(1, 1), 1000);
}
}
class RowView extends coconut.ui.View {
@:attribute var row:Row;
function render() '<div>{row.i}</div>';
}
class Data implements coconut.data.Model {
var rows:tink.state.ObservableArray<Row> = new tink.state.ObservableArray(
[for(i in 0...10) new Row({ i: i })]
);
}
class Row implements coconut.data.Model {
@:editable var i:Int;
}
Probably @:tracked
could somehow support an expression to support tracking the internals of some structures like ObservableMap?
like @:tracked(_.get('key'))
@:state var date:Date = '';
The above typing error is reported as
coconut/ui/macros/ViewBuilder.hx:174: characters 83-107 : tink.state.State<Date> should be tink.state.State<String>
class Main extends coconut.ui.View {
static function main() {}
function render() '<Page/>';
}
class Page extends coconut.ui.View {
function render() '<div/>';
override function afterInit(e) Extern.foo(('str':Int));
}
extern class Extern {
@:overload(function(s:String):Void {})
static function foo(i:Int):Void;
}
Error: (note that there are actually no "reasons" printed)
src/Main.hx:8: characters 36-59 : Could not find a suitable overload, reasons follow
The terminal process terminated with exit code: 1
Instead if the afterInit
is moved into the Main
class, we get:
src/Main.hx:4: characters 36-59 : Could not find a suitable overload, reasons follow
src/Main.hx:4: characters 36-59 : Overload resolution failed for i : Int -> Void
src/Main.hx:4: characters 47-58 : String should be Int
src/Main.hx:4: characters 47-58 : For function argument 'i'
src/Main.hx:4: characters 36-59 : Overload resolution failed for s : String -> Void
src/Main.hx:4: characters 47-58 : String should be Int
src/Main.hx:4: characters 47-58 : For function argument 's'
src/Main.hx:4: characters 36-59 : End of overload failure reasons
The terminal process terminated with exit code: 1
Not a bug, just a quick note not to forget (you can close the issue after reading, just thought putting this here as more chances to be useful than lost in a gitter chat).
Reading this article I noticed they use an interesting benchmark to compare different flavours of react.
Seems to be located here : https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html if it's still there.
That's all. So if there's a need one day for another benchmark we can look that up.
If I have a @:state or @:attr in a View class and it's only consumed by a subelement, then there are no lifecycles fired in my View class, however maybe I want to do some computation based on them.
The only hack I found so far, to reference these properties in the beginning of the render() function, but it's not really nice.
class Main extends coconut.ui.View {
@:ref var img:js.html.ImageElement;
function render() '<img ref=${img}/>';
static function main() {}
}
This use to work but in rc5 I get js.html.ImageElement should be Null<coconut.ui.Ref<xdom.Wrapped<js.html.ImageElement>>>
Given this view:
class Foo extends View {
@:state var bar = 1;
function render() '
<div>
<Child onblub={bar++} />
<span>{bar}</span>
</div>
';
}
The blub event handler is a function that always does the same thing, but at every rerender a new function gets created, thus invalidating the view.
For anonymous functions, it should be possible to find out which variables they capture (in this case none) and then use those (and the string represenation of the function's AST) as a cache key. For example in TodoMVC the item and function (event) todos.delete(item)
would be the cache key.
Specifically, references in @:computed
are additionally wrapped into autoobservable. Per @back2dos: @:comp
probably comes from tink_lang.
// Main.hx
class Main extends coconut.ui.View {
static function main() {}
function render() '<Foo/>';
}
// Foo.hx
class Foo extends coconut.ui.View {
function render() '<div/>';
function capture(e:Dummy) {}
}
Expected: Type not found : Dummy
Actual: this direct initialization causes the compiler to do really weird things
The following code no longer works in gen4
import coconut.ui.*;
class Dashboard extends View {
@:attr var sidebar:{className:String}->RenderResult;
function render() '<div/>';
}
class SideBar extends View {
@:attr var className:String;
function render() '<div/>';
}
class Main extends View {
static function main() {}
function render() '
<Dashboard><sidebar attr><SideBar ${...attr}/></sidebar></Dashboard>
';
}
Error (without position): Array<Unknown<0>> should be { className : String } -> coconut.ui.RenderResult
hi,
there is an example of integration of coconut with deepstate?
import coconut.Ui.hxx;
class Main extends coconut.ui.View {
static function main() {
trace(hxx('<Main/>'));
}
@:attr var onPress:Void->Void = null;
function render() '
<div>
<if ${onPress == null}>
<div onclick=${onPress}>Button</div>
<else>
No Button
</if>
</div>
';
}
Generated this:
Main.prototype = $extend(coconut_ui_View.prototype,{
onPress: function() {
(tink_state__$Observable_Observable_$Impl_$.get_value(this.__slots.onPress))();
return;
}
,render: function() {
var __r = [];
var __r1 = [];
if(this.onPress == null) {
var __ret = { onclick : tink_core__$Callback_Callback_$Impl_$.fromNiladic($bind(this,this.onPress))};
var __r2 = [];
__r2.push(coconut_vdom__$Child_Child_$Impl_$.ofText("Button"));
__r1.push(coconut_vdom__$Child_Child_$Impl_$.element("div",__ret,__r2));
} else {
__r1.push(coconut_vdom__$Child_Child_$Impl_$.ofText("No Button"));
}
__r.push(coconut_vdom__$Child_Child_$Impl_$.element("div",{ },__r1));
return __r[0];
}
,__initAttributes: function(attributes) {
var this1 = attributes.onPress;
this.__slots.onPress.setData(this1 == null ? this.__tink_defaults0.onPress : this1);
}
});
Note that this.onPress
will never be null because it is referencing the instance method. Also, the app will crash when trying to invoke onPress
, because get_value()
of the slot will give null
.
Looks like a serious regression.
I think some implicit casts failed. Treating the Dynamic
as an observable itself.
For example:
class MyView extends View<{data:Data}> {
override function afterInit(e) {
// allow accessing `data` here
}
}
Currently I store data
into a class member during render
, which doesn't feel too good.
Since @:computed
is supported, it'd make sense. Also one shouldn't have to create a model just to use this feature.
Counterpart to MVCoconut/coconut.data#38
I found a bug, but i don't know it's bug of VSHaxe or bug of coconut.ui (tink_*, etc).
It appears only when i use latest coconut.ui from git and latest tink libs from git.
Source code:
import js.Browser.*;
class Main {
public static function main() {
coconut.ui.Renderer.mount(document.body, new App({}));
}
}
class App extends coconut.ui.View {
var name:String;
function render() {
return hxx('<div>GOOD</div>');
}
}
When i hover on any item in class that extends coconut.ui.View, it shows "@:optional ..."
build.hxml
-cp src
-main Main
-lib coconut.ui
-lib coconut.vdom
-js out/main.js
Haxe Compiler 4.0.0-preview.5+da718a30e
Windows 7 x64
@:ref var something:Something;
@:computed var boink:Boink = something.boink; //stops updating when `something` changes
function render() '<Something ref=${something} />';
Workaround:
@:state var something:Something = null;
@:computed var boink:Boink = something.boink;
function render() '<Something ref=${v -> something = v} />';
using tink.CoreApi;
class Main extends coconut.ui.View {
@:attr var item:ItemData;
function render() '
<div>
<div>
<div>
<div>
<switch ${item.data}>
<case ${Loading}>
<case ${Done(data)}>
<div>
<div>
<div>
<div>
<a>${data.user}</a>
</div>
</div>
</div>
</div>
<case ${Failed(e)}>
</switch>
</div>
</div>
</div>
</div>
';
public static function main() {}
}
typedef ItemResponse = {
final user:SimpleUserResponse;
}
typedef SimpleUserResponse = {
final id:String;
final name:String;
}
class ItemData implements coconut.data.Model {
@:loaded var data:ItemResponse = null;
}
Somehow this requires a somewhat deep html hierarchy to reproduce.
(try removing one div wrapper and it will behave correctly)
Based on a few hours of playing around I think var attributes:vdom.Arr
causes memory leaking.
I could not figure out so far which porperty causes the leaking, or maybe the full object is leaking just it's visible because vdom.Attr is a huge object.
Right now the only render function can access the generic parameters in view classes.
For example in lifecycle events they can be essential to be able to access them and make computations, etc.
Also when delegate behavior from hxx to views it's not so convenient sometimes to pass all the parameters and it would be simpler to rely on class properties. I know this approach is not functional, but it should be the developer's choice which way he goes
When I try to define a ref for a custom component, it's current
property is always empty.
package;
import coconut.ui.View;
class HelloView extends View
{
@:attr var model:HelloModel;
@:ref var sub:js.html.Element;
function render()
{
return @hxx '<HelloSubView ref=${sub} />';
}
override function viewDidMount()
{
js.Browser.console.log("HelloView afterMounting", sub.current); //it's always null
}
override function viewDidUpdate()
{
js.Browser.console.log("HelloView afterPatching", sub.current); //it's always null
}
}
https://github.com/grosmar/coconut-playground/tree/gen4-lifecycle-bug
Looks like now all my application sizes grow extremely since latest version of coconut.
I looked into the generated js and it looks like if I have attributes that I never use DCE doesn't remove them anymore.
And because I still use var attributes:Attr
a lot, it generates a lot of code.
I will try to consolidate some topics that I think requires documentation/explanations. Some may belong to tink_hxx or specific renderer, but I am not sure:
View
class: performance, caching, allows state, etc<Parent><attr1 props><Child {...props}/></attr1></Parent>
class -> className
<div onclick={attr = value}/>
<- this works somehow, but the haxe expr is not a function at allfunction render() '<div attr={value}/>'
, what is the difference if value
is Observable vs a plain value?Feel free to add to the list.
Is it possible to make this work?
import coconut.data.*;
import coconut.ui.*;
import coconut.Ui.*;
class Main {
static function main() {
var h = hxx('<MyView />');
var e = h.toElement();
trace(h);
trace(e); // null
js.Browser.document.body.appendChild(e);
}
}
class MyView extends View<{}> {
function render() '
<switch ${int()}>
<case ${0}>
<div>Zero</div>
<case ${1}>
<div>One</div>
<case ${_}>
<div>Default</div>
</switch>
';
function int() return 1;
}
Me: I was wondering, is it possible to have multiple renderers in the same build. eg. lets say I want half of the app coconut.vdom and the other half coconut.pixi or something?
You: No
...
Me: you mean not at all, I mean also not when there are separate roots?
You: the problem is that currently, there are types such as RenderResult which tend to be quite useful, but if you want to have multiple backends, that won't fly
You: for me it's not that hard, but presenting a nice api to the user will be tricky ^^
you'll have to writeextends View<js.html.Node>
andextends View<pixijs.Sprite>
and what not
Me: ๐ก yeah orextends coconut.vdom.View
andextends coconut.pixi.View
. but I understand this is tricky and opens box of lesser nice api
You: ๐ก actually, that's pretty cool
You: can you please dump that in a ticker for me?
There you go! ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.