lukejacksonn / ijk Goto Github PK
View Code? Open in Web Editor NEWTransforms arrays into virtual dom trees; a terse alternative to JSX and h
License: MIT License
Transforms arrays into virtual dom trees; a terse alternative to JSX and h
License: MIT License
Hi!
Running the Hyperapp demo throws the exception TypeError: Cannot assign to read only property '0' of string 'Hello World'
.
Versions of the libraries:
JFYI The shape of vdom nodes has changed in Preact. See the following definition from their src/index.d.ts
:
interface VNode<P = {}> {
type: ComponentType<P> | string;
props: P & { children: ComponentChildren };
. . .
}
For the size of this library though, it's easier just to vendor it directly into what ever project you want and add explicit call to Preact.createElement
for the recursive base case. A similar fix for would make it work with React.
I've been using ijk for a little while and right now I think it is the best way to "write" HTML. \o/
But I also love copy & paste. =P
So I'm writing this thing so I can turn HTML into ijk: https://github.com/slacktracer/lmn.
I guess I'm asking... Is that OK with you?
Anyway, thank you very.
By the way, we must start campaigning to get ijk as one of the alternatives for JSX on the hyperapp readme sooner than later. =D
Sometimes you want to be able to skip a child. To do so you would usually return a falsey value. At the moment falsey values are rendered as an undefined
tag which is not ideal.
This:
const view = state => xyzd(
['main', [
true && ['h1', 'Visible'],
false && ['h1', 'Invisible']
]
)
Renders as:
<main>
<h1>Visible</h1>
<undefined>undefined</undefined>
</main>
See this behaviour on this CodePen
I mean, I thought I could this:
[
'main',
[
[
'label',
[
'examiners',
[
'input',
{
checked: state.section === 'examiners',
name: 'section',
onclick: () => actions.changeSection('examiners'),
type: 'radio'
}
]
]
]
]
But it does not work. Should it be possible? Am I missing something?
Looks like 0.16.0. 0.17.0, and 0.18.0 have all been published to npm
without any tags created. Might come in handy at some point.
ultradom is now superfine, it returns to the 'name, 'props', 'children'
signature, and it requires text nodes to be wrapped in a vnode: https://github.com/jorgebucaran/superfine/blob/master/src/index.js#L368-L381
var createVNode = function(name, props, children, element, key, type) {
return {
name: name,
props: props,
children: children,
element: element,
key: key,
type: type
}
}
var createTextVNode = function(text, element) {
return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
}
At the moment ['hr']
renders as <hr>undefined</hr>
and having nested arrays of children in children causes an error because [['li', 1], ['li',2]] is not a valid node. It would be nice to be able to support both of these cases.
Looks cool
Here's an idea:
Instead of strings for tag names use a set of functions so proper typing will provide auto complete and error throwing
Import { dom } from 'ijk'
const tree = h('name', 'props', 'children')(
['main', [
[dom.h1( 'Hello World')]
[dom.button({ onclick: console.log }, 'Log event ']
)
The expression ['p', 0]
does not render anything, whereas ['p', String(0)]
works.
Hi @lukejacksonn!
Thank you for this project! I am hoping to experiment with it as a way to write views in a virtual-Dom library independent way, so I hope you continue to support being able to specify the node structure and not just preact and hyperapp.
I have done an experiment with JSX here: https://meiosis.js.org/examples/setup
But I think an ijk/hyperscript version would be even cooler! I will give it a try.
Now, I was thinking, would it make sense to support emmet style tags such as ["button#save.btn.btn-primary", ...]
? I suppose you would also have to have a way to specify whether to use class
or className
, not sure...
What do you think?
Thank you!
I was unable so far to find a way to use ijk with @hyperapp/router (entirely). Have you ever?
I thought was almost there but I got stuck on (below):
const view = () =>
h(
"div",
null,
h(
"ul",
null,
h("li", null, h(Link, { to: "/" }, "Home")),
h("li", null, h(Link, { to: "/about" }, "About"))
),
h("hr"),
h(Route, { path: "/", render: home }),
h(Route, { path: "/about", render: about })
);
I did not find a way to turn this h(Link, { to: "/" }, "Home")
to "ijk"...
And this Link({ to: "/" })
does not seem to work at all...
I'm looking into this for a few days now but I got no more clues at the moment. Are they even compatible? Or, of course they are, and am I just being silly? ¯\(ツ)/¯
The attribute names of the output tree is the only difference between these two functions. I have tried various ways of making them one function that accepts a schema as an argument but I couldn't get it to work 🤔
export const h = node =>
!node
? false
: typeof node[1] === 'object' && !Array.isArray(node[1])
? {
name: node[0],
props: node[1],
children: Array.isArray(node[2])
? node[2].map(h).filter(Boolean)
: node[2] + '',
}
: h([node[0], {}, node[1]])
export const p = node =>
!node
? false
: typeof node[1] === 'object' && !Array.isArray(node[1])
? {
nodeName: node[0],
attributes: node[1],
children: Array.isArray(node[2])
? node[2].map(p).filter(Boolean)
: node[2] + '',
}
: p([node[0], {}, node[1]])
Ideally I would like to be able to just export h
which is configurable like:
h(['name', 'props', 'children']) // hyperapp trees
h(['nodeName', 'attributes', 'children']) // preact trees
Where the array values represent the key names of the vtree nodes.
{
[schema[0]]: node[0],
[schema[1]]: node[1],
[schema[2]]: Array.isArray(node[2]) ? node[2].map(p).filter(Boolean) : node[2] + '',
}
@lukejacksonn If jorgebucaran/hyperapp#578 lands, would you consider changing ijk so it can be used like this:
const { h } from "ijk"
h(['h1', 'Hello World'])
...without a call to h('name','props','children')
to create the actual h
function? In other words, have the exported h
return an opinionated Virtual DOM schema like { nodeName, attributes, children }.
I'd like to use this piece of code for io but it's missing the license information. Would you mind making this MIT licensed?
Cool lib!
What about
const clense = (a, b) => {
b && a.push.apply(a, b)
return a
}
or maybe?
const clense = (a, b) => {
b && a.push.apply(a, [b])
return a
}
to save some memory via mutating?
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.