BitstylesPhoenix.Component.Dropdown (bitstyles_phoenix v1.0.0-rc1) View Source

The dropdown component without any JS.

Link to this section Summary

Functions

Renders a dropdown component with a button, a menu and options.

Link to this section Functions

Renders a dropdown component with a button, a menu and options.

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. It also supports an optional menu slot, to add attributes on the menu (the content of the menu is not rendered).

The dropdown options can be passed in as slots, which will be passed down to the menu items. You can use ui_button with variant menu to render links that are prepared for the dropdown menu.

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 div

This slot will not render any inner content.

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"/>
...>   <:option>
...>     <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>   </:option>
...>   <:option>
...>     <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>   </:option>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative">
  <button class="a-button a-button--ui" type="button">
    <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 a-list-reset u-margin-s-top">
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        Option 1
      </a>
    </li>
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        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 />
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>     </:option>
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>     </:option>
...>   </.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 class="a-button a-button--ui" type="button">
      <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 a-list-reset a-dropdown--top u-margin-s-bottom">
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          Option 1
        </a>
      </li>
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          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 />
...>   <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>   </:option>
...>   <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>   </:option>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative u-flex u-justify-end">
  <button class="a-button a-button--ui" type="button">
    <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 a-list-reset a-dropdown--right u-margin-s-top">
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        Option 1
      </a>
    </li>
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        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 />
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>     </:option>
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>     </:option>
...>   </.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 class="a-button a-button--ui" type="button">
      <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 a-list-reset a-dropdown--top a-dropdown--right u-margin-s-bottom">
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          Option 1
        </a>
      </li>
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          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>
...>   <:option>
...>     <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>   </:option>
...>   <:option>
...>     <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>   </:option>
...> </.ui_dropdown>
...> """
"""
<div class="u-relative">
  <button class="a-button a-button--ui foo" type="button">
    Custom button content
  </button>
  <ul class="a-dropdown u-overflow--y a-list-reset u-margin-s-top">
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        Option 1
      </a>
    </li>
    <li>
      <a class="a-button a-button--menu u-h6" href="#">
        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"/>
...>     <:option class="foo">
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 1</.ui_button>
...>     </:option>
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 2</.ui_button>
...>     </:option>
...>     <:option role="separator"></:option>
...>     <:option>
...>       <.ui_button to="#" variant="menu" class="u-h6">Option 3</.ui_button>
...>     </:option>
...>   </.ui_dropdown>
...> </div>
...> """
"""
<div style="min-height: 200px; width: 500px;">
  <div class="u-relative">
    <button aria-controls="dropdown-1" class="a-button a-button--ui" onclick="toggle(&#39;dropdown-1&#39;)" type="button">
      <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 a-list-reset a-dropdown--full-width u-margin-s-top" id="dropdown-1" style="display: none">
      <li class="foo">
        <a class="a-button a-button--menu u-h6" href="#">
          Option 1
        </a>
      </li>
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          Option 2
        </a>
      </li>
      <li role="separator">
      </li>
      <li>
        <a class="a-button a-button--menu u-h6" href="#">
          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>