Atributos de HTML
Os atributos HTML nos modelos Markup são apenas atributos HTML. Uma mudança de comportamento específica está relacionada aos atributos booleanos e, além disso, seu conhecimento sobre os atributos HTML é transferido como está.
Atributos booleanos
Atributos booleanos em HTML são atributos que representam valores true ou false.
html`
<p hidden="false">hidden text</p>
<button disabled>click me</button>
<input type="checkbox" checked="false" />
`.render(document.body)
// <p hidden="false">hidden text</p> <- still hidden
// <button disabled="">click me</button>
// <input type="checkbox" checked="false"> <- still checkedO problema com atributos booleanos em HTML é que atribuir a eles o valor de false não interrompe seu efeito no elemento. Se estiverem presentes na tag funcionam como tendo o valor true independente do valor.
Markup respeita os valores true ou false e permite adicionar ou remover esses atributos apenas especificando seus valores booleanos.
const hidden = false
const disabled = true
const checked = false
html`
<p hidden="${hidden}">hidden text</p>
<button disabled="${disabled}">click me</button>
<input type="checkbox" checked="${checked}" />
`.render(document.body)
// <p>hidden text</p>
// <button disabled="true">click me</button>
// <input type="checkbox">Definir um valor de atributo como false (como string ou booleano) ou nulo (undefined ou null) removerá o atributo.
const disabled = false
const checked = null
html`
<p hidden="false">hidden text</p>
<button disabled="${disabled}">click me</button>
<input type="checkbox" checked="${checked}" />
`.render(document.body)
// <p>hidden text</p>
// <button>click me</button>
// <input type="checkbox">Atributos de valor
Markup está ciente do valor que você injeta no modelo como valores de atributos e irá rastreá-los e atualizá-los adequadamente. Não há sintaxe extra necessária para que isso aconteça.
const type = 'button'
const active = 'active'
const style = 'color: white; background: black'
html`
<button
type="${type}"
class="btn ${active} common"
style="border: none; ${style}"
>
click me
</button>
`.render(document.body)
// <button type="button" class="btn active common" style="border: none; color: white; background: black">click me</button>Atributos de evento
HTML permite declarar atributos de eventos embutidos e eles funcionam da mesma forma com marcação. Nenhuma sintaxe extra é necessária para adicionar eventos anexados, mas Markup faz coisas adicionais em segundo plano, sobre as quais você pode aprender mais lendo os documentos events.
const handleClick = (event) => {
console.log(event)
}
html`<button onclick="${handleClick}">click me</button>`Atributo de referência
Uma coisa que existe em Markup e não em HTML é o atributo ref que permite criar uma referência a um elemento que você pode usar para acessar o elemento DOM renderizado para qualquer operação necessária. Você pode ler sobre referências para mais detalhes.
html`<button ref="btn">click me</button>`Atributos como objeto
É bom conhecer antecipadamente todos os atributos possíveis, mas às vezes isso não é possível. Para isso, você pode coletar atributos como objetos e apenas injetá-los conforme necessário.
const [count, setCount] = state(0)
const btn = ({ text = 'click me', ...props }) =>
html` <button ${props} type="button">${text}</button>`
const countUp = () => {
setCount((prev) => prev + 1)
}
const temp = html`
<p>${count}</p>
${button({ text: '+', ariaLabel: 'count up button', onClick: countUp })}
`
/* renders:
<p>0</p>
<button type="button" aria-label="count up button">+</button>
*/
temp.render(document.body)Qualquer atributo definido após a injeção do objeto de atributo substituirá o valor do nome do atributo do objeto. No exemplo acima, garantimos que o type do botão seja sempre button configurando-o após a injeção do objeto props.
Além disso, você pode usar o nome do atributo camelcase para alterá-lo para kebab-case. No exemplo acima, ariaLabel se tornará aria-label quando o botão for renderizado. O onClick será alterado para onclick e tratado como atributos de evento.