choojs / nanohtml

:dragon: HTML template strings for the Browser with support for Server Side Rendering in Node.
MIT License
687 stars 49 forks source link

Support for conditional attributes? #164

Open saschanaz opened 5 years ago

saschanaz commented 5 years ago
html`
  <div data-something-optional="${nullableValue}"></div>
`

It can be useful if we get a declarative HTML way to conditionally define an attribute. Thoughts?

cc @sidvishnoi

saschanaz commented 5 years ago

It seems the feature already exists but is limited to the specific attributes.

https://github.com/choojs/nanohtml/blob/bdd0efe65b1e9c26e04723588a19e629ca86fdde/lib/bool-props.js#L3-L8

sidvishnoi commented 5 years ago

@saschanaz Although I like the implicit nullablitly, a better syntax for above could be:

<div data-something?="${nullableValue}"></div>

It'll also avoid a rare but potential clash with having optional in attribute name.

goto-bus-stop commented 5 years ago

A way to do this today is using object spread:

const optional = {}
if (nullableValue) optional['data-something-optional'] = nullableValue
html`
  <div ${optional}></div>
`

it's a bit verbose but I think I prefer it over introducing custom syntax.

It is a bit strange that undefined and null values still output the attribute imo. I would maybe like to see that change in a future major release.

e; it can be made less verbose with a helper,

function optional (attr, value) {
  if (value) return { [attr]: value }
  return {}
}
html`
  <div ${optional('data-something', nullableValue)}></div>
`
saschanaz commented 5 years ago

It'll also avoid a rare but potential clash with having optional in attribute name.

The -optional was just an arbitrary name rather than a way to make it optional 😁

html`
 <div ${optional('data-something', nullableValue)}></div>
`

Seems less verbose than inserting conditional block everywhere 👍, but is <div ${object}> a documented feature?

goto-bus-stop commented 5 years ago

it looks like it's missing from the docs, yes. it is definitely a tested and supported feature, though!

saschanaz commented 4 years ago
<div data-something?="${nullableValue}"></div>

It'll also avoid a rare but potential clash with having optional in attribute name.

? still is a valid attribute character.

document.createRange().createContextualFragment("<a what?='abc'>").children[0].getAttribute("what?")
// "abc"