BitstylesPhoenix.Component.Dropdown.ui_dropdown

You're seeing just the function ui_dropdown, go back to BitstylesPhoenix.Component.Dropdown module for more information.

Renders a dropdown component with a button and a menu.

In order for this component to work you have to provide extra JS like shown in the examples.

The dropdown supports a default button that can either render with a label and a icon or with completly custom content. The dropdown options can be passed to the menu slot as inner content. Options can be rendered with ui_dropdown_option/1.

Attributes

  • class - Extra classes to pass to the outer div See BitstylesPhoenix.Helper.classnames/1 for usage.
  • variant - The dropdown variant (top, right, full-width). Can be provided as an atom, a string, a list of atoms or a list of strings.
  • All other attributes are passed on to the outer div

This component will not render any inner content except slots.

Attributes - menu slot

  • class - Extra classes to pass to the ul dropdown menu See BitstylesPhoenix.Helper.classnames/1 for usage.
  • All other attributes are passed on to the outer ul

This slot will render any inner content as the menu. Children are expected to be <li>.

Attributes - button slot

  • class - Extra classes to pass to the dropdown button See BitstylesPhoenix.Helper.classnames/1 for usage.
  • label - The button for the label. If set, will not render custom button content.
  • icon_file - The external SVG file with icons to be passed on to BitstylesPhoenix.Component.Icon.ui_icon/1 for the dropdown icon. Only needed if SVG icons are not provided inline and if not rendering custom button content.

This slot will render it's inner content when no button label is set.

Minimal dropdown with defaults without JS

iex> assigns = %{}
...> render ~H"""
...> <.ui_dropdown>
...>   <:button label="Select me"/>
...>   <:menu>
...>     <.ui_dropdown_option href="#" class="u-h6">
...>       Option 1
...>     </.ui_dropdown_option>
...>     <.ui_dropdown_option href="#" class="u-h6">
...>       Option 2
...>     </.ui_dropdown_option>
...>   </:menu>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative">
  <button type="button" class="a-button a-button--ui">
    <span class="a-button__label">
      Select me
    </span>
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="a-icon a-icon--m a-button__icon" focusable="false" height="16" width="16">
      <use xlink:href="#icon-caret-down">
      </use>
    </svg>
  </button>
  <ul class="a-dropdown u-overflow-y-auto a-list-reset u-margin-s-top">
    <li>
      <a href="#" class="a-button a-button--menu u-h6">
        Option 1
      </a>
    </li>
    <li>
      <a href="#" class="a-button a-button--menu u-h6">
        Option 2
      </a>
    </li>
  </ul>
</div>
"""

Requires additional content on the page:

<svg xmlns="http://www.w3.org/2000/svg" hidden aria-hidden="true">
  <symbol id="icon-caret-down" viewBox="0 0 100 100">
    <path d="M6.64,34.23a5.57,5.57,0,0,1,7.87-7.89L49.92,61.91,85.49,26.34a5.57,5.57,0,0,1,7.87,7.89L53.94,73.66a5.58,5.58,0,0,1-7.88,0Z" fill-rule="evenodd"/>
  </symbol>
</svg>

Dropdown with menu variant top

iex> assigns = %{}
...> render ~H"""
...> <div style="min-height: 150px;" class="u-flex u-flex-col">
...>   <div class="u-flex-grow-1"></div>
...>   <.ui_dropdown variant={:top}>
...>     <:button label="Select me"/>
...>     <:menu>
...>       <.ui_dropdown_option href="#" class="u-h6">
...>         Option 1
...>       </.ui_dropdown_option>
...>       <.ui_dropdown_option href="#" class="u-h6">
...>         Option 2
...>       </.ui_dropdown_option>
...>     </:menu>
...>   </.ui_dropdown>
...> </div>
...> """
"""
<div style="min-height: 150px;" class="u-flex u-flex-col">
  <div class="u-flex-grow-1">
  </div>
  <div class="u-relative">
    <button type="button" class="a-button a-button--ui">
      <span class="a-button__label">
        Select me
      </span>
      <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="a-icon a-icon--m a-button__icon" focusable="false" height="16" width="16">
        <use xlink:href="#icon-caret-down">
        </use>
      </svg>
    </button>
    <ul class="a-dropdown u-overflow-y-auto a-list-reset a-dropdown--top u-margin-s-bottom">
      <li>
        <a href="#" class="a-button a-button--menu u-h6">
          Option 1
        </a>
      </li>
      <li>
        <a href="#" class="a-button a-button--menu u-h6">
          Option 2
        </a>
      </li>
    </ul>
  </div>
</div>
"""

Requires additional content on the page:

<svg xmlns="http://www.w3.org/2000/svg" hidden aria-hidden="true">
  <symbol id="icon-caret-down" viewBox="0 0 100 100">
    <path d="M6.64,34.23a5.57,5.57,0,0,1,7.87-7.89L49.92,61.91,85.49,26.34a5.57,5.57,0,0,1,7.87,7.89L53.94,73.66a5.58,5.58,0,0,1-7.88,0Z" fill-rule="evenodd"/>
  </symbol>
</svg>

Dropdown with menu variant right

iex> assigns = %{}
...> render ~H"""
...> <.ui_dropdown variant="right">
...>   <:button label="Select me"/>
...>   <:menu>
...>     <.ui_dropdown_option href="#">
...>       Option 1
...>     </.ui_dropdown_option>
...>     <.ui_dropdown_option href="#">
...>       Option 2
...>     </.ui_dropdown_option>
...>   </:menu>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative u-flex u-justify-end">
  <button type="button" class="a-button a-button--ui">
    <span class="a-button__label">
      Select me
    </span>
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="a-icon a-icon--m a-button__icon" focusable="false" height="16" width="16">
      <use xlink:href="#icon-caret-down">
      </use>
    </svg>
  </button>
  <ul class="a-dropdown u-overflow-y-auto a-list-reset a-dropdown--right u-margin-s-top">
    <li>
      <a href="#" class="a-button a-button--menu">
        Option 1
      </a>
    </li>
    <li>
      <a href="#" class="a-button a-button--menu">
        Option 2
      </a>
    </li>
  </ul>
</div>
"""

Requires additional content on the page:

<svg xmlns="http://www.w3.org/2000/svg" hidden aria-hidden="true">
  <symbol id="icon-caret-down" viewBox="0 0 100 100">
    <path d="M6.64,34.23a5.57,5.57,0,0,1,7.87-7.89L49.92,61.91,85.49,26.34a5.57,5.57,0,0,1,7.87,7.89L53.94,73.66a5.58,5.58,0,0,1-7.88,0Z" fill-rule="evenodd"/>
  </symbol>
</svg>

Dropdown with menu variant top right

iex> assigns = %{}
...> render ~H"""
...> <div style="min-height: 150px;" class="u-flex u-flex-col">
...>   <div class="u-flex-grow-1"></div>
...>   <.ui_dropdown variant={[:top, :right]}>
...>     <:button label="Select me"/>
...>     <:menu>
...>       <.ui_dropdown_option href="#" class="u-h6">
...>         Option 1
...>       </.ui_dropdown_option>
...>       <.ui_dropdown_option href="#" class="u-h6">
...>         Option 2
...>       </.ui_dropdown_option>
...>     </:menu>
...>   </.ui_dropdown>
...> </div>
...> """
"""
<div style="min-height: 150px;" class="u-flex u-flex-col">
  <div class="u-flex-grow-1">
  </div>
  <div class="u-relative u-flex u-justify-end">
    <button type="button" class="a-button a-button--ui">
      <span class="a-button__label">
        Select me
      </span>
      <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="a-icon a-icon--m a-button__icon" focusable="false" height="16" width="16">
        <use xlink:href="#icon-caret-down">
        </use>
      </svg>
    </button>
    <ul class="a-dropdown u-overflow-y-auto a-list-reset a-dropdown--top a-dropdown--right u-margin-s-bottom">
      <li>
        <a href="#" class="a-button a-button--menu u-h6">
          Option 1
        </a>
      </li>
      <li>
        <a href="#" class="a-button a-button--menu u-h6">
          Option 2
        </a>
      </li>
    </ul>
  </div>
</div>
"""

Requires additional content on the page:

<svg xmlns="http://www.w3.org/2000/svg" hidden aria-hidden="true">
  <symbol id="icon-caret-down" viewBox="0 0 100 100">
    <path d="M6.64,34.23a5.57,5.57,0,0,1,7.87-7.89L49.92,61.91,85.49,26.34a5.57,5.57,0,0,1,7.87,7.89L53.94,73.66a5.58,5.58,0,0,1-7.88,0Z" fill-rule="evenodd"/>
  </symbol>
</svg>

Custom button content

iex> assigns = %{}
...> render ~H"""
...> <.ui_dropdown>
...>   <:button class="foo">Custom button content</:button>
...>   <:menu>
...>     <.ui_dropdown_option href="#" class="u-h6">
...>       Option 1
...>     </.ui_dropdown_option>
...>     <.ui_dropdown_option href="#" class="u-h6">
...>       Option 2
...>     </.ui_dropdown_option>
...>   </:menu>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative">
  <button type="button" class="a-button a-button--ui foo">
    Custom button content
  </button>
  <ul class="a-dropdown u-overflow-y-auto a-list-reset u-margin-s-top">
    <li>
      <a href="#" class="a-button a-button--menu u-h6">
        Option 1
      </a>
    </li>
    <li>
      <a href="#" class="a-button a-button--menu u-h6">
        Option 2
      </a>
    </li>
  </ul>
</div>
"""

Drop down with some JS and full-width variant and icon file

iex> assigns = %{}
...> render ~H"""
...> <div style="min-height: 200px; width: 500px;">
...>   <.ui_dropdown variant="full-width">
...>     <:button onclick="toggle('dropdown-1')" aria-controls={"dropdown-1"} label="Select me" icon_file="assets/icons.svg" />
...>     <:menu style="display: none" id="dropdown-1">
...>       <.ui_dropdown_option href="#" class="foo">
...>         Option 1
...>       </.ui_dropdown_option>
...>       <.ui_dropdown_option href="#">
...>         Option 2
...>       </.ui_dropdown_option>
...>       <li role="separator"></li>
...>       <.ui_dropdown_option href="#">
...>         Option 3
...>       </.ui_dropdown_option>
...>     </:menu>
...>   </.ui_dropdown>
...> </div>
...> """
"""
<div style="min-height: 200px; width: 500px;">
  <div class="u-relative">
    <button type="button" aria-controls="dropdown-1" class="a-button a-button--ui" onclick="toggle(&#39;dropdown-1&#39;)">
      <span class="a-button__label">
        Select me
      </span>
      <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="a-icon a-icon--m a-button__icon" focusable="false" height="16" width="16">
        <use xlink:href="assets/icons.svg#icon-caret-down">
        </use>
      </svg>
    </button>
    <ul class="a-dropdown u-overflow-y-auto a-list-reset a-dropdown--full-width u-margin-s-top" id="dropdown-1" style="display: none">
      <li>
        <a href="#" class="a-button a-button--menu foo">
          Option 1
        </a>
      </li>
      <li>
        <a href="#" class="a-button a-button--menu">
          Option 2
        </a>
      </li>
      <li role="separator">
      </li>
      <li>
        <a href="#" class="a-button a-button--menu">
          Option 3
        </a>
      </li>
    </ul>
  </div>
</div>
"""

Requires additional content on the page:

<script>
  function toggle(element) {
    var e = document.getElementById(element);
    if (e.style.display === "none") {
      e.style.display = "block";
    } else {
      e.style.display = "none";
    }
  }
</script>