Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Are there ways to integrate with hyperscript interfaces? #72

Open
chrisrzhou opened this issue Apr 27, 2023 · 4 comments
Open

Comments

@chrisrzhou
Copy link

chrisrzhou commented Apr 27, 2023

Love the ideas and approach of arrow-js. I believe this tiny thing is going to be the next big thing for many developers who are interested in committing to JS and away from JS frameworks.

I have a question if arrow-js or html templates have possible integration points with hyperscript's h interface. Since h is the underlying interface for many other JS frameworks e.g. React.createElement, Vue.h, Mithril.m, and is also agnostic, being able to integrate/map with html in some ways would open up adoption paths to arrow-js from other frameworks.

If this should live outside of arrow-js, is there a general direction how arrow-js.html can be mapped to h?

type H = <P extends object>(
  tag: string,
  props: P,
  children: H | H[],
);

// how to map between "arrow.html <-> h"
// example html's `@click` and `@input` mappable to `props[click|onClick]` and `props[change|onChange]` based on some mapping object?

Thank you for your time.

@justin-schroeder
Copy link
Owner

Great question — and fundamentally the answer is no, but with all things — it depends. Some important things to note:

  • Arrow does not use a virtual DOM and is fundamentally incompatible with the Virtual DOM concept.
  • Arrow uses fine-grained reactivity to only transform things that need to be reactive.

To be fair these points are not very well spelled out, and the currently published code base is "experimental" in that its a first pass at the concept so some of the benefits (performance) of this approach are not yet realized (has moderate performance rather than blazing fast performance 😂).

That said, it would be possible to decompose html blocks into h function calls, but I’m not sure it provides any significant benefit? Would love to understand the pros of this approach more before make any judgement on it. What use cases can you think of? As for architecture I do believe future versions will include additional hooks for the kinds of extensions you’re describing.

@chrisrzhou
Copy link
Author

chrisrzhou commented Apr 27, 2023

Hey @justin-schroeder, thanks for your prompt reply.

The motivation here is to see if arrow-js can offer a feature while taking one less opinionated behavior (i.e. "always using document.createElement to create nodes):

arrow-js accepts a custom hyperscript-compatible function on initialization (document.createElement by default).
The default behavior renders to DOM (current arrow-js behavior), but one can provide a custom h and basically benefit from arrow-js.html as a templating engine, without modification to the features and API e.g. do not support any form of VDOM.

I'm not sure how this would entirely work, but one might provide the possible values of h:

  • React.createElement: which manages a VDOM tree that React eventually renders. In fact this promotes non-JSX/non-transpile development flow of React as JSX is technically optionally (it's just a DX feature), since everything is using React.createElement under the hood.
  • MyCustomCreateElement: which does custom things e.g. I can write a h method that just assembles a JSON tree for testing/debugging.

I want to stress I'm not proposing any changes to arrow-js's API, but was wondering if it is possible to abstract h (with document.createElement as the default value) to configure arrow-js. This might open the doors to migration from other frameworks.

Example of how it "may" work?

import { configure } from 'arrow-js';

configure({h: document.createElement}); // no need to configure but stating as an example
configure({
  h: React.createElement,
  mapHtmlProps,
}); // provide a custom createElement and `mapProps`

const mapHtmlProps = { // gives a chance to map from the consumer interface to arrow-js/lit's `html`
  click: 'onClick',
  class: 'className',
}

html`<button @click="${() => console.log('clicked')}"`

// evaluates to React.createElement('button', { onClick: () => console.log('clicked') }); etc

Motivation for this question comes from my personal exploration on creating framework-agnostic style/theming libraries i.e. uinix-ui which works in any h-friendly library (e.g. React, Preact, Solid, Mithril, htm etc), so the motivation derives from there.

@chrisrzhou
Copy link
Author

chrisrzhou commented Apr 27, 2023

I'll take a jab at this idea and see if it can be made configurable and maybe share some ideas back later!

I see potential in https://github.com/justin-schroeder/arrow-js/blob/master/src/html.ts#L400 as a way to override h (i.e. document.createElement). However html is DOM-based, so more changes might be needed. But the main idea is to decouple DOM-based logic in html into configurable methods that consumers can provide while letting arrow-js keep to its current logic and behaviors.

I don't think this is simple to do, and not suggesting any changes. Mostly just curious if such a configuration makes sense, which may enable adoption in the JS community via:

  • to allow integrations with arrow-js
  • prefer arrow-js or lit ES6 template syntax more than frameworks using transpilation. In a sense if custom h is supported, users can utilize arrow-js.html to author markup, further bringing the community closer to it and lit.
  • support SSR
  • improve migration paths from other frameworks.

@bbqbaron
Copy link

What use cases can you think of?

For my part, it's that editing normal functions is much easier than editing embedded string literals. Arrow is so stripped down (which is great) that it seems like an odd requirement for me to find custom IDE tooling to get autocomplete, shortcuts, linting, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants