4 puan yazan GN⁺ 2025-03-08 | 1 yorum | WhatsApp'ta paylaş
  • Düğmeler, dinamik web uygulamaları oluşturmak için vazgeçilmezdir. Menü açmak, işlemler arasında geçiş yapmak ve form göndermek için kullanılırlar
  • Chrome 135, önceki popovertargetaction ve popovertarget özniteliklerini iyileştirip onların yerini alan yeni command ve commandfor özniteliklerini sunuyor
  • Düğme davranışını mevcut yöntemlerle uygularken ortaya çıkan sorunlar:
    • HTML içindeki onclick işleyicileri, güvenlik politikaları (CSP) nedeniyle gerçek kodda kullanım açısından kısıtlanabilir
    • Düğme ile diğer öğelerin durumunu senkronize etmek gerekir ve erişilebilirliği koruyarak durumu yöneten kod karmaşıktır
    • React, AlpineJS, Svelte gibi ortamlarda da durum ve olay yönetimi karmaşıktır

command ve commandfor deseni

  • command ve commandfor öznitelikleri kullanıldığında düğmeler diğer öğeler üzerinde bildirimsel şekilde işlem yapabilir. Bu, esnekliği korurken framework rahatlığı sağlar
  • commandfor düğmesi ID kullanır (for özniteliğine benzer) ve command, yerleşik değerler alarak daha sezgisel bir yaklaşım sunar
  • Örnek: menü açma düğmesi oluşturma
    • aria-expanded ya da ek JavaScript gerekmez
    <button commandfor="my-menu" command="show-popover">  
      Open Menu  
    </button>  
    <div popover id="my-menu">  
      <!-- ... -->  
    </div>  
    

command ve commandfor ile popovertargetaction ve popovertarget karşılaştırması

  • popover kullandıysanız popovertarget ve popovertargetaction özniteliklerine aşina olabilirsiniz
  • Bunlar, commandfor ve command ile benzer şekilde çalışır ancak popover'a özeldir
  • Yeni öznitelikler eskilerin tamamen yerini alır ve ek işlevler sunar

Yerleşik komutlar

  • command özniteliği, çeşitli API'lerle eşlenen davranışları yerleşik olarak içerir
    • show-popover: el.showPopover() ile eşlenir
    • hide-popover: el.hidePopover() ile eşlenir
    • toggle-popover: el.togglePopover() ile eşlenir
    • show-modal: dialogEl.showModal() ile eşlenir
    • close: dialogEl.close() ile eşlenir
  • Örnek: silme onayı diyaloğu oluşturma
    • JavaScript olmadan durum ve erişilebilirlik yönetilebilir
    <button commandfor="confirm-dialog" command="show-modal">  
      Delete Record  
    </button>  
    <dialog id="confirm-dialog">  
      <header>  
        <h1>Delete Record?</h1>  
        <button commandfor="confirm-dialog" command="close" aria-label="Close">  
          <img role="none" src="/close-icon.svg">  
        </button>  
      </header>  
      <p>Are you sure? This action cannot be undone</p>  
      <footer>  
        <button commandfor="confirm-dialog" command="close" value="cancel">  
          Cancel  
        </button>  
        <button commandfor="confirm-dialog" command="close" value="delete">  
          Delete  
        </button>  
      </footer>  
    </dialog>  
    
    • Sonuç işleme kodu: dönüş değeri, diyaloğun close olayında işlenebilir
    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");  
      }  
    });  
    

Özel komutlar

  • Yerleşik komutlara ek olarak, -- öneki kullanılarak özel komutlar tanımlanabilir
  • Özel komutlar hedef öğe üzerinde "command" olayını tetikler, ancak ek bir mantık yürütmez
  • Örnek: görsel döndürme komutu oluşturma
    <button commandfor="the-image" command="--rotate-landscape">  
      Landscape  
    </button>  
    <button commandfor="the-image" command="--rotate-portrait">  
      Portrait  
    </button>  
    <img id="the-image" src="photo.jpg">  
    
    <script type="module">  
      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";  
        }  
      });  
    </script>  
    

Shadow DOM'da komut işleme

  • Shadow DOM içinde commandfor, ID tabanlı çalıştığı için şu kısıtlar vardır:
    • Shadow DOM'lar arasında öğe referansı verilemez
    • Bu durumda .commandForElement özelliğini ayarlamak için JavaScript API kullanılabilir
  • Örnek: Shadow DOM içinde komut bağlama
    <my-element>  
      <template shadowrootmode="open">  
        <button command="show-popover">Show popover</button>  
        <slot></slot>  
      </template>  
      <div popover><!-- ... --></div>  
    </my-element>  
    
    <script>  
      customElements.define("my-element", class extends HTMLElement {  
        connectedCallback() {  
          const popover = this.querySelector('[popover]');  
          this.shadowRoot.querySelector('button').commandForElement = popover;  
        }  
      });  
    </script>  
    

Gelecek planları

  • Chrome, ek yerleşik komutlar sunmayı planlıyor:
    • <details> öğesini açma ve kapatma
    • <input> ve <select> için show-picker komut desteği
    • <video> ve <audio> için oynatma komutları
    • Öğedeki metni kopyalama işlevi

1 yorum

 
GN⁺ 2025-03-08
Hacker News görüşleri
  • Programlama dili kuramcıları 80'lerden beri gotonun daha güçlü bir sürümü olan comefrom hakkında spekülasyon yapıyor. Bu yalnızca intercal'de uygulanmıştı. intercal, C gibi dillere göre güvenlik, performans ve ergonomi açısından üstün olsa da ticari pazara girmekte zorlanıyor. javascript'in intercal'in bu özelliğini entegre ettiğini görmek ilginç. Umarım bu, javascript'in closure tabanlı nesnelerinin fonksiyonel programlamayı ana akıma taşıması gibi, nazik programlamada bir patlamaya yol açar

  • Invokers yalnızca Chrome'a özgü değil. Firefox nightly'de de zaten kullanılabiliyor

  • JS olmadan bildirime dayalı UI davranışı uygulama fikri çekici

    • popover/modal boilerplate'ini ortadan kaldırıyor (aria-expanded ile oynamaya gerek yok)
    • show-modal gibi yerleşik komutlar erişilebilirliği doğrudan işaretlemeye entegre ediyor
    • özel komutlar (örn. --rotate-landscape), bileşenlerin HTML üzerinden API sunabilmesini sağlıyor
  • Soru işaretleri:

    • Soyutlama vs. sihir: Bu sadece karmaşıklığı JS'den HTML'e taşımak mı? Framework'ler zaten durumu soyutluyor. Bu nasıl bir arada var olacak?
    • Shadow DOM sürtüşmesi: Shadow root'lar arasında .commandForElement ayarlamak için JS gerekiyor. Bu, ancak yarısı çözülmüş bir sorun gibi görünüyor
    • Geleceğe hazırlık: OpenUI 20'den fazla komut eklerse (örn. show-picker, toggle-details), platform niş sözdizimleriyle şişecek mi?
  • Spesifikasyon:

    • button element, commandfor özelliği
    • button element, command özelliği
  • Bu, Next, Be, Apple vb.'nin yaklaşık 30 yıl önce kullandığı action/messaging deseni mi, yoksa benim kaçırdığım bir şey mi var?

    • Kullanışlıydı, ancak temel tasarım desenini korumanın getirdiği karmaşıklık nedeniyle interface tabanlı controller desenine evrildi. Bu yüzden bu kutu açılırsa çok sayıda iyileştirme talebi geleceğini tahmin ediyorum
  • Netscape'in erken dönem Java UI toolkit'i (IFC), action öğelerinin bağlanmasına izin veriyordu

  • Yeni command ve commandfor özellikleri, popovertargetaction ve popovertarget özelliklerini iyileştiriyor ve onların yerini alıyor

    • Bunlar artık varsayılan olarak kullanılabilir mi? Yerini almak tam olarak ne demek? Bir gün bunları kaldıracaklar mı? Web geliştiricileri artık ihtiyaç duyulmayan şeyleri bir güncellemeyle kaldıramaz
  • String'lerle programlamaya karşı tamamen alerjik tepki veriyorum. Erişilebilirlik avantajını anlıyorum ama bir başka web uygulaması davranış katmanı için öğe ID'lerinin kullanılmasına özellikle heyecan duymuyorum

  • Bunun tam API olmadan uygulanmaması gerekirdi. Yaklaşık 5 komut yerine, HTML üzerinden tüm JavaScript işlevlerini uygulamak mümkünmüş gibi görünüyor. Bu da binlerce komut anlamına gelebilir

  • HTML'de command and conquer için bir beklenti vardı

  • HTML'yi iyileştirmek ve genişletmek güzel ama önümüzde hâlâ uzun bir yol var. HTMX ekibinin bazı iyi fikirleri var