Rails, Popper, Tailwind & Stimulus

Popper is a javascript positioning engine to speed up the development of popovers and tooltips.

More information about it can be found here

Project setup:

Rails 7
Stimulus 2
esbuild / jsbuild
Tailwind CSS

rails new project_name –css tailwind –j…


This content originally appeared on DEV Community and was authored by Stéphane

Popper is a javascript positioning engine to speed up the development of popovers and tooltips.

More information about it can be found here

Project setup:

  • Rails 7
  • Stimulus 2
  • esbuild / jsbuild
  • Tailwind CSS

rails new project_name --css tailwind --javascript esbuild

Step 1: add popper to the project

yarn add @popperjs/core

Step2: create a stimulus controller

rails g stimulus popper

Open the popper_controller.js and perform the following edits:

Add at the top of the file:

import { createPopper } from "@popperjs/core";

Before creating an instance of popper in the controller, let's add "target" and "values" to make this controller more reusable.

Image description

Popper instance is instantiated in the connect() method

connect() {
    // Create a new Popper instance
    this.popperInstance = createPopper(this.elementTarget, this.tooltipTarget, {
      placement: this.placementValue,
      modifiers: [
        {
          name: "offset",
          options: {
            offset: this.offsetValue,
          },
        },
      ],
    });
  }

Note that the event listeners are not added to the target or element from within the stimulus controller. As written in Better Stimulus and the official stimulus documentation, event management should be handled by the Stimulus framework. We will attached the event management to the element using the data-action tag as explained below.

Let's create the show and hide methods as well as the disconnect one that us used to remove the popper instance.

show(event) {
    this.tooltipTarget.setAttribute("data-show", "");

    // We need to tell Popper to update the tooltip position
    // after we show the tooltip, otherwise it will be incorrect
    this.popperInstance.update();
  }

  hide(event) {
    this.tooltipTarget.removeAttribute("data-show");
  }

  // Destroy the Popper instance
  disconnect() {
    if (this.popperInstance) {
      this.popperInstance.destroy();
    }
  }

So far we are pretty much sticking to popper's documentation. The main difference is that the event listeners are not attached to the element programmatically within the stimulus controller.

At this point, the popper_controller.js file should look like this:

import { Controller } from "@hotwired/stimulus";
import { createPopper } from "@popperjs/core";

// Connects to data-controller="popper"
export default class extends Controller {
  static targets = ["element", "tooltip"];
  static values = {
    placement: { type: String, default: "top" },
    offset: { type: Array, default: [0, 8] },
  };

  connect() {
    // Create a new Popper instance
    this.popperInstance = createPopper(this.elementTarget, this.tooltipTarget, {
      placement: this.placementValue,
      modifiers: [
        {
          name: "offset",
          options: {
            offset: this.offsetValue,
          },
        },
      ],
    });
  }

  show(event) {
    this.tooltipTarget.setAttribute("data-show", "");

    // We need to tell Popper to update the tooltip position
    // after we show the tooltip, otherwise it will be incorrect
    this.popperInstance.update();
  }

  hide(event) {
    this.tooltipTarget.removeAttribute("data-show");
  }

  // Destroy the Popper instance
  disconnect() {
    if (this.popperInstance) {
      this.popperInstance.destroy();
    }
  }
}

Step 3: Let's get stylish!

We can use the one provided by the popper team as an example on their website

#tooltip {
  background: #333;
  color: white;
  font-weight: bold;
  padding: 4px 8px;
  font-size: 13px;
  border-radius: 4px;
  display: none;
}
#arrow,
#arrow::before {
  position: absolute;
  width: 8px;
  height: 8px;
  background: inherit;
}

#arrow {
  visibility: hidden;
}

#arrow::before {
  visibility: visible;
  content: "";
  transform: rotate(45deg);
}
#tooltip[data-popper-placement^="top"] > #arrow {
  bottom: -4px;
}

#tooltip[data-popper-placement^="bottom"] > #arrow {
  top: -4px;
}

#tooltip[data-popper-placement^="left"] > #arrow {
  right: -4px;
}

#tooltip[data-popper-placement^="right"] > #arrow {
  left: -4px;
}

#tooltip[data-show] {
  display: block;
}

Feel free to use tailwind CSS styles and animation or any other CSS trick that is required or will make your popover/tooltip look better.

Saved it in app/assets/stylesheets/popper.css and import it at the top of app/assets/stylesheets/application.tailwind.css

@import "popper.css";

/* Tailwind CSS */
@tailwind base;
@tailwind components;
@tailwind utilities;

It's now time to work on the frontend of the project!

Step 4: Let's create a button

<div data-controller="popper">
   <button id="button" data-popper-target="element" data-action="mouseenter->popper#show mouseleave->popper#hide" class="bg-blue-500 text-blue-100 px-3 py-2 rounded-xl">
      Click me
      <div id="tooltip" role="tooltip" data-popper-target="tooltip">
         My tooltip
         <div id="arrow" data-popper-arrow></div>
      </div>
   </button>
</div>

As stated above, the event listeners are added using the data-action parameter. in this case we direct the mouseenter event, which is triggered when the mouse is over the button, to the show method defined in the controller. When the mouse is no longer over the button element, mouseleave is triggered and the hide method is called to hide the tooltip.

You can add more actions or adapt to your needs. For example, you can have data-action="click->popper#show" to open a popover when a user click on a certain element.

Step 5: Enjoy

Image description


This content originally appeared on DEV Community and was authored by Stéphane


Print Share Comment Cite Upload Translate Updates
APA

Stéphane | Sciencx (2022-01-17T12:11:37+00:00) Rails, Popper, Tailwind & Stimulus. Retrieved from https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/

MLA
" » Rails, Popper, Tailwind & Stimulus." Stéphane | Sciencx - Monday January 17, 2022, https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/
HARVARD
Stéphane | Sciencx Monday January 17, 2022 » Rails, Popper, Tailwind & Stimulus., viewed ,<https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/>
VANCOUVER
Stéphane | Sciencx - » Rails, Popper, Tailwind & Stimulus. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/
CHICAGO
" » Rails, Popper, Tailwind & Stimulus." Stéphane | Sciencx - Accessed . https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/
IEEE
" » Rails, Popper, Tailwind & Stimulus." Stéphane | Sciencx [Online]. Available: https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/. [Accessed: ]
rf:citation
» Rails, Popper, Tailwind & Stimulus | Stéphane | Sciencx | https://www.scien.cx/2022/01/17/rails-popper-tailwind-stimulus/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.