-
Notifications
You must be signed in to change notification settings - Fork 171
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
is
property, or make html clean again
#81
Comments
Hi @dy. The issue with this approach is that invoking a function is fundamentally different than passing a component reference as the tag name. Component references can be classes or functions, and their calling signature is actually much more nuanced than simply Also, the tag name used when FWIW, in prior versions of HTM, there was an optional syntax that's sortof similar to what you showed: html`
<@c ${NavBar} />
<@c ${App}>
.. etc
</@c>
` However, it didn't make sense to preserve this in the 2.0 parser since it was just a workaround intermediary to allow complex tag names in HTML. |
Actually class ExpandableList extends HTMLUListElement { ... }
customElements.define('expandable-list', ExpandableList, {extends: 'ul'})
<ul is="expandable-list">
</ul> That would be genuinely strong improvement for some framework to abandon jsx components in favor of native custom elements. Just using hooks to create native custom elements. function CustomComponent(props) {
// hooks-based code (fx is shorthand for useEffect)
fx(() => {
// attachedCallback
return () => {
// detachedCallback
}
}, [])
}
htm`
<ul is=${CustomComponent}></ul>
` Melding that approach with htm would allow to register custom elements on the fly, because in DOM creating custom element takes redundant And most importantly - this would be strong step off the bundling. <link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
<script>
import htm from 'https://unpkg.com/htm'
// Register MaterialUI custom elements
function Button(element, props) {
element.mdcButton = new mdc.button.MDCButton
element.mdcRipple = new mdc.ripple.MDCRipple
}
function App () {
return htm`<button is=${Button} class="mdc-button">Button</button>`
}
</script> |
Just so I'm following along properly, what's the difference between your example and this one? <link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
<script>
import htm from 'https://unpkg.com/htm'
// Register MaterialUI custom elements
class Button extends HTMLButtonElement {
static toString(){ return 'mcw-button'; }
constructor() {
super();
this.mdcButton = new mdc.button.MDCButton
this.mdcRipple = new mdc.ripple.MDCRipple
}
}
customElements.define(Button+'', Button);
function App () {
return htm`<${Button} class="mdc-button">Button<//>`
}
</script> |
@developit good point, I overlooked that, there's no difference for custom elements to be passed directly as tags. Personally I prefer Just found an Easter egg of htm. Some special html`
<${document.body}>
<div>Our app code to render into body</div>
<//>
<${document.querySelector('.dialogs-container')}>
<section is=${Dialog}>Portal code</section>
<//>
` that's not possible with JSX. That enables quite elegantly portals, side-effects, hydration and rids of |
woah. that is bloody clever........... |
For the curious, here's the implementation: import { createElement } from 'preact';
import { createPortal } from 'preact/compat';
export function h(tag, props, child) {
if (typeof tag === 'object' && tag && 'ownerDocument' in tag) {
return createPortal(child, tag);
}
return createElement.apply(this, arguments);
} |
More I play around with possible syntax of hypothetical framework, more I discover how brilliant htm is. // react fragments are well-supported
html`<></>`
// seems that we don't need second slash for closing tag
html`<a></>`
//direct properties are possible
html`<mount=${target}></mount>`
// ↑ meaning literally a `mount` property of a fragment
// calls h({mount: target}) |
Ok, the only questionable potential aspect of htm is anonymous props: htm`<a ${disabled}></a>` That could be useful in some situations, but the implementation isn't clear. The rest addressed by this issue can be solved with external framework. |
that is cursed...so i had to implement it https://stackblitz.com/edit/node-wup3qi?file=index.html |
htm looks brilliant so far.
The only thing that does not seem elegant is components. Both having tag name as variable and having closing tag seems external to html syntax. Besides, trying to couple components with semantic HTML oftentimes brings unnecessary wrapping and long nesting, also creates shallow tags like Contexs, Providers, HOCs etc.
A possible elegant way to bring clean html to htm would be making components just modifiers for actual tags, like
Compared to current code:
That idea would allow collapsing HOCs/Providers as well:
Just wonder - if that's worth of separate package and what's possible way to introduce that to htm.
The text was updated successfully, but these errors were encountered: