Command и CommandFor

Содержание

В своём докладе про диалог и поповер упоминал про proposal, который добавляет возможность вызывать диалог декларативно.

В чём суть?

Ранее для открытия диалога нам обязательно нужен был JS на странице с вызовом метода dialog.showModal():

<dialog id="my-dialog">
  Диалог
</dialog>
<button id="dialog-openner">
  Открыть диалог
</button>
<script>
  const dialog = document.getElementById("my-dialog");
  const openDialogButton = document.getElementById("dialog-openner");
  openDialogButton.addEventListener("click", () => {
    dialog.showModal();
  });
</script>

Неудобно.

Когда разрабатывали Popover API, об этом подумали и добавили возможность вызывать поповер декларативно — через атрибуты popovertarget и popovertargetaction:

<div
  id="my-popover"
  popover
>
  Поповер
</div>
<button
  popovertarget="my-popover"
  popovertargetaction="show"
>
  Открыть поповер
</button>

Захотелось такое иметь и для диалога. И теперь эта хотелка стала реальностью.

Новые атрибуты command и commandfor

Начиная с Chrome 135, можно вызывать диалог и поповер через связку атрибутов command и commandfor:

<dialog id="my-dialog">
  Диалог
</dialog>
<button
  commandfor="my-dialog"
  command="show-modal"
>
  Открыть диалог
</button>

Они работают по такому же принципу, что и popovertarget с popovertargetaction, но имеют дополнительные плюшки — например, добавляют под капотом aria-атрибуты по типу aria-details, aria-expanded.

command имеет 5 встроенных значений:

  • show-popover — эквивалент el.showPopover()
  • hide-popover — эквивалент el.hidePopover()
  • toggle-popover — эквивалент el.togglePopover()
  • show-modal — эквивалент dialog.showModal()
  • close — эквивалент dialog.close()

Также можно указать кастомную команду через -- и добавить для неё обработчик в JS:

<button
  commandfor="my-element"
  command="--my-custom-command"
>
  Кастомная команда
</button>

<div id="my-element">
  Элемент
</div>

<script>
  const element = document.getElementById("my-element");
  element.addEventListener("command", (event) => {
    if (event.command === "--my-custom-command") {
      console.log("my-custom-command");
    }
  });
</script>

Более подробно с новой фичей можно познакомиться в статье Хрома, либо в эксплейнере OpenUI.


P.S. Странно, что не добавили декларативный аналог для метода dialog.show(). Как будто бы может тоже пригодиться. Интересно, почему так сделали — в эксплейнере не нашёл этому объяснения.