codemix / babel-plugin-hyperhtml Goto Github PK
View Code? Open in Web Editor NEWBabel plugin which compiles JSX into hyperHTML
License: MIT License
Babel plugin which compiles JSX into hyperHTML
License: MIT License
As explained in here, I'd like to know if there's any interest in improving the current transformation or if I should just fork this and try to make it work as intended.
There is a little, but huge, change that opens doors for this transformation in a pretty seamless way.
JSX
const { Component, bind } = hyperHTML;
class Rando extends Component {
render() {
return this.html(
<Sub value={1 + this.props.rand} />
<Sub value={2 + this.props.rand} />
);
}
}
class Sub extends Component {
render() {
return this.html(
<div>
Value <strong>{this.props.value}</strong>
</div>
);
}
}
const render = bind(document.body);
render(
<div>
<Rando rand={Math.random()} />
</div>
);
should become
const { Component, bind } = hyperHTML;
class Rando extends Component {
render() {
return this.html`
${node => {
const comp = Sub.for(node);
comp.props = {value: 1 + this.props.rand};
return comp.render();
}}
${node => {
const comp = Sub.for(node);
comp.props = {value: 2 + this.props.rand};
return comp.render();
}}
`;
}
}
class Sub extends Component {
render() {
return this.html`
<div>
Value <strong>${this.props.value}</strong>
</div>
`;
}
}
const render = bind(document.body);
render`
<div>
${node => {
const comp = Rando.for(node);
comp.props = {rand: Math.random()};
return comp.render();
}}
</div>
`;
enabling the following features:
.render()
will be automatically invoked the component would already have updated props (or the same if not computed at runtime).The rule is pretty simple:
<ComponentName attr1={123} attr2=456 attr3={what('ever')} />
Should become
${node => {
const comp = ComponentName.for(parent);
comp.props = {attr1: 123, attr2: 456, attr3: what('ever')};
return comp.render();
}}
So that attributes would be passed as props.
The JSX surrounding parenthesis will mark the beginning and the end of the Template Literal, and holes found outside components should be replaced by ${}
instead of {}
so that this:
render(
<div onclick={event => alert(event.target)}>
<Comp stuff={'cool'} />
</div>
);
would become
render`
<div onclick=${event => alert(event.target)}>
${node => {
const comp = Comp.for(node);
comp.props = {stuff: 'cool'};
return comp.render();
}}
</div>
`;
I hope all details are clear enough.
I am not sure it makes sense to pass along children, since each component can create those directly in the render method, and use props to define children, i.e.
<ComponentName sub={['first child', 'last child']} />
So, actually, I think for the time being having just the proposed transform would be awesome.
You had this idea and I'm trying to make it happen for the whole hyperHTML user-base, which I'm pretty sure would appreciate the possibility of using JSX to simplifying lightweight components usage in hyperHTML instead of Custom Elements.
Thanks in advance for considering this or, eventually, for sharing your thoughts on this.
Best Regards.
Code Pen live here https://codepen.io/WebReflection/pen/MPxBzJ?editors=0010
quick heads-up, the produced code with that extra
object won't ever work:
const Greet = _arg => {
let {name, ...extra} = _arg;
return wire(_arg)`<div ${extra}><h1>Hi ${name}</h1></div>`;
}
attributes always need to be assigned to a name
the following will create a new Greet every render time
class DemoComponent extends Component {
render() {
return this.html`<div class="test">
${new Greet({name: "Alice", class: "greeter"})}
<p>This is some text</p>
</div>`;
}
}
It'd be awesome if inner components could be related to their owner. At the end of the day, writing <Greet />
is not less static than a div
so ... how about some helper to make it possible?
// used for every component
const comp = (self, i, Class, data) => {
// either quick and dirty or via WeakMap
const c = (self.__comp || (self.__comp = []))[i] ||
(self.__comp[i] = new Class);
c.setState(data);
return c;
};
class DemoComponent extends Component {
get defaultState() { return {class: null, name: ''}; }
render() {
return this.html`
<div class="test">
${comp(this, 0, Greet, {name: "Alice", class: "greeter"})}
<p>This is some text</p>
</div>`;
}
}
class Greet extends Component {
render() {
return this.html`
<div class=${this.state.class}>
<h1>Hi ${this.state.name}</h1>
</div>`;
}
}
The i
in the comp
helper is the index of the component. In this way you update the same component each time instead of creating a new one.
If the setState(data)
is not a good pattern, then the component should expose a way to be updated or its render should look for props
.
const comp = (self, i, Class, props) => {
const c = (self.__comp || (self.__comp = []))[i] ||
(self.__comp[i] = new Class);
// set props and return the rendered/updated node
c.props = props;
return c.render();
};
// ... same code as before ...
class Greet extends Component {
render() {
return this.html`
<div class=${this.props.class}>
<h1>Hi ${this.props.name}</h1>
</div>`;
}
}
Thoughts ?
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.