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

Allow users to register element names #167

Open
dfabulich opened this issue May 4, 2020 · 2 comments
Open

Allow users to register element names #167

dfabulich opened this issue May 4, 2020 · 2 comments

Comments

@dfabulich
Copy link

https://github.com/esxjs/esx looks a lot like HTM, but instead of handling components as <${Foo}>, you have to (get to?) pre-register component names, like this: esx.register({Foo})

Then you can use custom components like this:

esx`<Foo bar=baz>Blah</Foo>`

It would be cool if this were an option for HTM as well.

@yhatt
Copy link
Contributor

yhatt commented Jan 30, 2021

You can bind a function works like a proxy to render pre-registered components.

import { h, render } from 'https://unpkg.com/preact?module';
import htm from 'https://unpkg.com/htm?module';

const App = ({ children }) => ['Hello, ', children, '!']

// Imitation of createEsx()
const createEsx = (components) =>
  htm.bind((type, ...rest) => h(components[type] || type, ...rest))

const esx = createEsx({ App })
render(esx`<App>world</App>`, document.getElementById('app'))

@developit
Copy link
Owner

@yhatt exactly! There's also a way to do this for everything rendered by Preact, including elements created via h() and JSX:

import { options, h, render } from 'https://unpkg.com/preact?module';
import htm from 'https://unpkg.com/htm?module';
const html = htm.bind(h);

// component registry
const components = {};
components.App = ({ children }) => ['Hello, ', children, '!'];

// inject component registry into Preact itself:
let old = options.vnode;
options.vnode = vnode => {
  if (vnode.type in components) vnode.type = components[vnode.type];
  if (old) old(vnode);
};

// now it's global!
render(html`<App>world</App>`, document.body);
// or:
render(h('App', {}, 'world'), document.body);

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