View Source Turboprop (Turboprop v0.1.4)

Tools

Turboprop consists of multiple tools, each with their own purpose in building your component library.

Turboprop Hooks

Turboprop Hooks allow adding a ton of accessibility features to your components by simply adding a hook and a few data attributes to them.
This includes:

  • Keyboard interactions
  • Focus management
  • ARIA attributes

You can either install and use them through the hex.pm dependency and some helpers we offer to add the relevant attributes to a component, or install them directly through npm and adding the attributes yourself.

As an example, this renders a fully accessible dropdown menu:

<div {menu()}>
  <button
    class="rounded-md bg-blue-500 px-3 py-1.5 text-sm text-white shadow-sm hover:bg-blue-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500"
    {menu_trigger()}
  >
    Menu
  </button>
  <div {menu_positioner()}>
    <div
      class="z-10 w-48 text-sm origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
      {menu_content()}
    >
      <Phoenix.Component.link navigate="/link" class="block px-4 py-2 outline-0 data-[highlighted]:bg-gray-100" {menu_item()}>
        Link
      </Phoenix.Component.link>
      <a href="/anchor" id="test" class="block px-4 py-2 outline-0 data-[highlighted]:bg-gray-100" {menu_item()}>Anchor</a>
    </div>
  </div>
</div>

Turboprop Merge

Turboprop Merge allows you to easily merge a list of Tailwind Classes to avoid style conflicts.

Imagine this component:

attr :class, :string, doc: "Class override"
def button(assigns) do
  ~H"""
  <button class={["bg-black px-3 py-1.5 text-sm", @class]}>Click me!</button>
  """
end

And imagine wanting to make the text a little bigger as a one-off. You've already added a @class attribute, but rendering the component with class="text-lg" will lead to an HTML output of "bg-black px-3 py-1.5 text-sm text-lg", with two competing font size classes.

Now, replace the class attribute with class={merge(["bg-black px-3 py-1.5 text-sm", @class])} and you will magically get "bg-black px-3 py-1.5 text-lg".