Dropdown

A floating panel of actions. The classes paint the panel and its rows; nothing here positions anything. Kobalte positions with a popper that writes inline styles, and a CSS-only dropdown anchors the panel itself, so placement stays with whatever opens the menu.

alpha The class names and states here are stable. The look is not: these styles can change in a minor release, without a major version bump.

ClassDoes what
dropdown-contentThe floating panel: raised surface, border, shadow
menuThe list inside it: a column with gaps
menu-itemA row: padding, radius, hover surface
menu-activeThe highlighted row
menu-disabledA disabled row: greyed out and inert
menu-titleA group heading inside the menu
menu-shortcutTrailing text in a row, pushed to the end

The panel

Shown open and in place. Use <ul> and <li> and the rows stay semantic; Kobalte renders divs with menu roles instead.

<ul class="dropdown-content menu">
    <li class="menu-item">Commit <span class="menu-shortcut">⌘K</span></li>
    <li class="menu-item menu-active">Push <span class="menu-shortcut">⇧⌘K</span></li>
    <li class="menu-item menu-disabled">Update project</li>
    <li><hr /></li>
    <li>
      <ul class="menu">
        <li class="menu-title">Branches</li>
        <li class="menu-item">main</li>
        <li class="menu-item">develop</li>
      </ul>
    </li>
</ul>

On the Kobalte tab the rows carry no classes: role="menuitem", data-highlighted and data-disabled are bound to .menu-item, .menu-active and .menu-disabled by /classless/kobalte.

With a trigger

The trigger is an ordinary button. Kobalte marks it data-expanded while the menu is open, and flips a DropdownMenu.Icon inside it.

<details open>
  <summary class="btn">Git settings ▾</summary>
  <ul class="dropdown-content menu" style="margin-top: 0.25rem">
    <li class="menu-item">Commit</li>
    <li class="menu-item">Push</li>
  </ul>
</details>

Submenus

A DropdownMenu.SubTrigger is a row that is also a trigger, so it takes .menu-item and picks up data-highlighted like any other row. Its SubContent is another panel.

<ul class="dropdown-content menu">
    <li class="menu-item menu-active">GitHub <span class="menu-shortcut">›</span></li>
  </ul>
</div>
<ul class="dropdown-content menu" style="margin-top: 0.25rem">
    <li class="menu-item">Create pull request…</li>
    <li class="menu-item">Sync fork</li>
</ul>