4 pontos por GN⁺ 2025-03-08 | 1 comentários | Compartilhar no WhatsApp
  • Botões são essenciais para criar aplicações web dinâmicas. Eles são usados para abrir menus, alternar ações e enviar formulários
  • No Chrome 135, os novos atributos command e commandfor melhoram e substituem os antigos atributos popovertargetaction e popovertarget
  • Problemas que surgiam ao implementar o comportamento de botões até agora:
    • O manipulador onclick do HTML pode ter uso limitado em código real por causa da política de segurança (CSP)
    • É necessário sincronizar o estado entre o botão e outros elementos, e o código para gerenciar esse estado mantendo a acessibilidade é complexo
    • Em React, AlpineJS, Svelte e outros, o gerenciamento de estado e de eventos também é complexo

Padrão command e commandfor

  • Com os atributos command e commandfor, um botão pode agir de forma declarativa sobre outro elemento. Isso oferece a conveniência dos frameworks, mantendo a flexibilidade
  • O botão com commandfor usa um ID (de forma parecida com o atributo for), e command aceita valores embutidos para uma abordagem mais intuitiva
  • Exemplo: implementação de um botão para abrir menu
    • Não é necessário aria-expanded nem JavaScript adicional
    
      Open Menu
    
    

command e commandfor vs popovertargetaction e popovertarget

  • Se você já usou popover, talvez conheça os atributos popovertarget e popovertargetaction
  • Eles funcionam de forma semelhante a commandfor e command, mas são específicos para popover
  • Os novos atributos substituem completamente os anteriores e oferecem funcionalidades adicionais

Comandos embutidos

  • O atributo command já traz embutidos comportamentos mapeados para várias APIs
    • show-popover: mapeado para el.showPopover()
    • hide-popover: mapeado para el.hidePopover()
    • toggle-popover: mapeado para el.togglePopover()
    • show-modal: mapeado para dialogEl.showModal()
    • close: mapeado para dialogEl.close()
  • Exemplo: implementação de um diálogo de confirmação de exclusão
    • É possível gerenciar estado e acessibilidade sem JavaScript
    
      Delete Record
    
        Delete Record?
    
      Are you sure? This action cannot be undone
    
          Cancel
    
          Delete
    
    
    • Código para tratar o resultado: é possível processar o valor de retorno no evento close do diálogo
    dialog.addEventListener("close", (event) => {
      if (event.target.returnValue === "cancel") {
        console.log("Cancel was clicked");
      } else if (event.target.returnValue === "delete") {
        console.log("Delete was clicked");
      }
    });
    

Comandos personalizados

  • Além dos comandos embutidos, é possível definir comandos personalizados usando o prefixo --
  • Comandos personalizados disparam o evento "command" no elemento de destino, mas não executam lógica adicional
  • Exemplo: implementação de um comando para rotacionar imagem
    
      Landscape
    
      Portrait
    
      const image = document.getElementById("the-image");
      image.addEventListener("command", (event) => {
        if (event.command === "--rotate-landscape") {
          image.style.rotate = "-90deg";
        } else if (event.command === "--rotate-portrait") {
          image.style.rotate = "0deg";
        }
      });
    
    

Tratamento de comandos no Shadow DOM

  • No Shadow DOM, como commandfor funciona com base em ID, existem as seguintes limitações:
    • Não é possível referenciar elementos entre Shadow DOMs diferentes
    • Nesse caso, é possível usar a API JavaScript para definir a propriedade .commandForElement
  • Exemplo: ligação de comando no Shadow DOM
    
        Show popover
    
      customElements.define("my-element", class extends HTMLElement {
        connectedCallback() {
          const popover = this.querySelector('[popover]');
          this.shadowRoot.querySelector('button').commandForElement = popover;
        }
      });
    
    

Planos futuros

  • No Chrome, há planos para adicionar mais comandos embutidos:
    • abrir e fechar o elemento
    • suporte ao comando show-picker em e
    • comandos de reprodução para e
    • função de copiar texto de elementos

1 comentários

 
GN⁺ 2025-03-08
Comentários do Hacker News
  • Teóricos de linguagens de programação especulam desde os anos 80 sobre comefrom, uma versão mais poderosa de goto. Isso só foi implementado no INTERCAL. O INTERCAL é superior a linguagens como C em segurança, desempenho e ergonomia, mas tem enfrentado dificuldades para entrar no mercado comercial. É interessante ver o JavaScript incorporando esse recurso do INTERCAL. Espero que isso leve a um aumento da programação educada, assim como os objetos baseados em closures do JavaScript levaram a programação funcional ao mainstream

  • Invokers não são algo exclusivo do Chrome. Já estão disponíveis também no Firefox Nightly

  • A ideia de implementar comportamento declarativo de UI sem JS é atraente

    • Remove o boilerplate de popovers/modais (sem necessidade de manipular aria-expanded)
    • Comandos embutidos como show-modal integram acessibilidade à marcação
    • Comandos personalizados (ex.: --rotate-landscape) permitem que componentes exponham APIs via HTML
  • Dúvidas:

    • Abstração vs. mágica: isso só está movendo a complexidade do JS para o HTML? Frameworks já abstraem estado. Como isso vai coexistir?
    • Atrito com Shadow DOM: é preciso JS para definir .commandForElement entre shadow roots. Isso parece um problema resolvido só pela metade
    • Preparação para o futuro: se o OpenUI adicionar mais de 20 comandos (ex.: show-picker, toggle-details), a plataforma vai inchar com sintaxe de nicho?
  • Especificação:

    • elemento button, atributo commandfor
    • elemento button, atributo command
  • Isso é o padrão de ação/mensageria que Next, Be, Apple etc. usavam há cerca de 30 anos, ou estou deixando passar alguma coisa?

    • Isso era útil, mas evoluiu para um padrão de controlador baseado em interface por causa da complexidade de manter o padrão básico de design. Então, se essa caixa for aberta, espero muitos pedidos de melhoria
  • O antigo toolkit Java de UI da Netscape (IFC) permitia conectar elementos de ação

  • Os novos atributos command e commandfor melhoram e substituem popovertargetaction e popovertarget

    • Eles agora estão disponíveis por padrão? O que significa exatamente “substituem”? Isso será removido algum dia? Desenvolvedores web não podem simplesmente remover, em uma atualização, algo que deixou de ser necessário
  • Tenho alergia total a programar com strings. Entendo os benefícios de acessibilidade, mas não me anima particularmente usar IDs de elementos como mais uma camada de comportamento de app web

  • Não deveriam ter implementado isso sem a API completa. Em vez de uns 5 comandos, parece que seria possível implementar toda a funcionalidade de JavaScript via HTML. Isso daria milhares de comandos

  • Eu estava esperando algo sobre command and conquer em HTML

  • Melhorar e expandir o HTML é bom, mas ainda há um longo caminho pela frente. O pessoal do HTMX tem algumas boas ideias