<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stephane Paquet</title>
    <description>The latest articles on DEV Community by Stephane Paquet (@spaquet).</description>
    <link>https://dev.to/spaquet</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F583684%2F41e4b1b3-5d0d-4620-a8d3-40d56ff2b5a8.jpeg</url>
      <title>DEV Community: Stephane Paquet</title>
      <link>https://dev.to/spaquet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spaquet"/>
    <language>en</language>
    <item>
      <title>Gemtracker v1.0.5 is here!</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Sun, 05 Apr 2026 02:30:38 +0000</pubDate>
      <link>https://dev.to/spaquet/gemtracker-v105-is-here-3cep</link>
      <guid>https://dev.to/spaquet/gemtracker-v105-is-here-3cep</guid>
      <description>&lt;p&gt;Gemtraker is a terminal-based TUI (written in Go with BubbleTea) that makes it way easier to understand and manage your Ruby bundle.&lt;/p&gt;

&lt;p&gt;Just run it in any project that has a Gemfile.lock and you instantly get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full visibility into every gem version (direct + transitive dependencies)&lt;/li&gt;
&lt;li&gt;Outdated gem detection with latest version info
&lt;/li&gt;
&lt;li&gt;CVE/vulnerability highlighting so you can quickly spot risky transitive gems
&lt;/li&gt;
&lt;li&gt;Interactive dependency tree (forward &amp;amp; reverse)
&lt;/li&gt;
&lt;li&gt;Tabs for Gems, Search, CVEs, and detailed views with direct links to RubyGems &amp;amp; GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s perfect for day-to-day dependency hygiene and compliance work (SOC 2, security audits, etc.) where you need to prove exactly what’s in your supply chain.If you work with Ruby or Rails projects, I’d love for you to give it a spin!&lt;/p&gt;

&lt;p&gt;Test it, break it, share feedback, suggest features, or submit a PR — all contributions are very welcome. &lt;a href="https://github.com/spaquet/gemtracker" rel="noopener noreferrer"&gt;https://github.com/spaquet/gemtracker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking forward to your thoughts, support and contributions! &lt;/p&gt;

</description>
      <category>cli</category>
      <category>ruby</category>
      <category>security</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Introducing Listopia: Collaborative List Management with AI Magic</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Sat, 28 Jun 2025 15:27:56 +0000</pubDate>
      <link>https://dev.to/spaquet/introducing-listopia-collaborative-list-management-with-ai-magic-26cm</link>
      <guid>https://dev.to/spaquet/introducing-listopia-collaborative-list-management-with-ai-magic-26cm</guid>
      <description>&lt;p&gt;I’m thrilled to share Listopia, the first open-source collaborative list management app with AI-powered multi-channel publishing (MCP) support, built on Rails. &lt;/p&gt;

&lt;p&gt;Whether you’re organizing tasks, brainstorming ideas, or tracking projects, Listopia makes it seamless with natural language controls—manage your lists like you’re chatting with a friend!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Listopia?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Collaborate Effortlessly: Work together on lists in real-time.&lt;/li&gt;
&lt;li&gt;AI-Powered: Use natural language to create and manage lists with MCP support.
&lt;/li&gt;
&lt;li&gt;Open Source: Free to use, extend, and contribute to!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check it out at &lt;a href="https://listopia-dhv.pages.dev" rel="noopener noreferrer"&gt;https://listopia-dhv.pages.dev&lt;/a&gt; and join the community on &lt;a href="https://github.com/spaquet/listopia" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;I’d love your feedback, ideas, or contributions! What do you think about using AI to supercharge list management? Drop a comment below or star us on GitHub!&lt;/p&gt;




&lt;p&gt;PS, we use &lt;a href="https://github.com/crmne/ruby_llm" rel="noopener noreferrer"&gt;Ruby LLM&lt;/a&gt; so you're not stuck with only one AI.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>productivity</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Startup Growth, AI, and Leadership: My Chat with Anna 🎙️🚀</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Fri, 27 Dec 2024 00:50:46 +0000</pubDate>
      <link>https://dev.to/spaquet/startup-growth-ai-and-leadership-my-chat-with-anna-ikc</link>
      <guid>https://dev.to/spaquet/startup-growth-ai-and-leadership-my-chat-with-anna-ikc</guid>
      <description>&lt;p&gt;Had the privilege of being a guest on Anna's podcast! 🎙️ We talked about everything from AI transforming the workplace to scaling startups, growth strategies, and the founder's journey. 🚀&lt;/p&gt;

&lt;p&gt;Anna brought so much energy and asked amazing questions that made for a truly engaging conversation.&lt;/p&gt;

&lt;p&gt;Check it out if you're curious about how startups grow, innovate, and navigate challenges: &lt;a href="https://youtu.be/u9Y-yAiskck" rel="noopener noreferrer"&gt;https://youtu.be/u9Y-yAiskck&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>startup</category>
      <category>leadership</category>
      <category>innovation</category>
    </item>
    <item>
      <title>AI &amp; Personas</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Thu, 12 Dec 2024 17:54:04 +0000</pubDate>
      <link>https://dev.to/spaquet/ai-personas-248m</link>
      <guid>https://dev.to/spaquet/ai-personas-248m</guid>
      <description>&lt;p&gt;Yesterday I asked ChatGPT to generate tech predictions for the year 2025 in the style of Marc Andreessen.&lt;/p&gt;

&lt;p&gt;Why Marc Andreessen? Well, Marc is one of the most successful VC in the Silicon Valley and a very prominent figure. He also post his own predictions about what the tech will look like in 1 year or more from now so I assumed that ChatGPT has enough knowledge about him, his style and vision of the tech scene.&lt;/p&gt;

&lt;p&gt;Here is the result of this one time exercise with ChatGPT: &lt;a href="https://medium.com/@spaquet/top-10-technology-trends-for-2025-f2dc56896947" rel="noopener noreferrer"&gt;https://medium.com/@spaquet/top-10-technology-trends-for-2025-f2dc56896947&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm now going to ask Claude the exact same question, but will change the style to have answers from another prominent person in tech.&lt;/p&gt;

&lt;p&gt;Happy Holidays 🎉&lt;/p&gt;

</description>
      <category>genai</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Mailcatcher for beginners</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Mon, 14 Mar 2022 21:46:29 +0000</pubDate>
      <link>https://dev.to/spaquet/mailcatcher-for-beginners-i3f</link>
      <guid>https://dev.to/spaquet/mailcatcher-for-beginners-i3f</guid>
      <description>&lt;p&gt;When in need to troubleshoot email messages use Mailcatcher.&lt;/p&gt;

&lt;p&gt;Mailcatcher is a simple SMTP server that you can run locally or remotely intercept emails during test and development phases.&lt;/p&gt;

&lt;p&gt;Once captured by Mailcatcher emails can be rendered from within their web interface and exported to be opened in any mail client.&lt;/p&gt;

&lt;p&gt;Mailcatcher web interface is refreshed in realtime when your app is using websocket otherwise every 30 seconds.&lt;/p&gt;

&lt;p&gt;Mailcatcher is language agnostic and simple to use as you just have to redirect SMTP traffic to Mailcatcher smtp port 1025.&lt;/p&gt;

&lt;p&gt;So, let's say that you have an application that uses an external SMTP provider and that you have Mailcatcher running locally, you just need to replace your third party provider by smtp://127.0.0.1:1025 and done!&lt;/p&gt;

&lt;p&gt;To access Mailcatcher web interface, simply point to &lt;a href="http://127.0.0.1:1080" rel="noopener noreferrer"&gt;http://127.0.0.1:1080&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If for any reason your instance of Mailcatcher is using a different IP address, just adapt the above examples.&lt;/p&gt;

&lt;p&gt;Over the years, I found it more convenient to not install Mailcatcher on my computer, but have it running in a docker image.&lt;/p&gt;

&lt;p&gt;Here are few ways to have it up and running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker run --rm -p 1080:1080 -p 1025:1025 --name mailcatcher stpaquet/alpinemailcatcher&lt;/code&gt; Will delete the image once you are done using it. This could be interesting for a test environment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker run -d -p 1080:1080 -p 1025:1025 --name mailcatcher stpaquet/alpinemailcatcher&lt;/code&gt; Will launch the image as a daemon.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker run -it -p 1080:1080 -p 1025:1025 --name mailcatcher stpaquet/alpinemailcatcher&lt;/code&gt; Will launch the image in interactive mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;br&gt;
Mailcatcher homepage: &lt;a href="https://mailcatcher.me" rel="noopener noreferrer"&gt;mailcatcher.me&lt;/a&gt;&lt;br&gt;
Dockerfile and Docker Compose: &lt;a href="https://github.com/spaquet/docker-alpine-mailcatcher" rel="noopener noreferrer"&gt;https://github.com/spaquet/docker-alpine-mailcatcher&lt;/a&gt;&lt;br&gt;
Dockerhub: &lt;a href="https://hub.docker.com/r/stpaquet/alpinemailcatcher" rel="noopener noreferrer"&gt;https://hub.docker.com/r/stpaquet/alpinemailcatcher&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Longer article can be found on Medium with Docker Compose basic configuration and more examples:  &lt;a href="https://medium.com/@spaquet/mailcatcher-to-the-rescue-4ba438dc98c2" rel="noopener noreferrer"&gt;https://medium.com/@spaquet/mailcatcher-to-the-rescue-4ba438dc98c2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>smtp</category>
      <category>mailcatcher</category>
      <category>programming</category>
      <category>docker</category>
    </item>
    <item>
      <title>Rails 7 + Devise + Log out</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Mon, 21 Feb 2022 19:41:47 +0000</pubDate>
      <link>https://dev.to/spaquet/rails-7-devise-log-out-d1n</link>
      <guid>https://dev.to/spaquet/rails-7-devise-log-out-d1n</guid>
      <description>&lt;p&gt;A Quick and Dirty way to get the redirection working on Logout when using Devise in a Rails 7 app.&lt;/p&gt;

&lt;p&gt;You probably have noticed that most of the redirects in Devise a somehow broken. This is due to the way Turbo interfere with them as it catches the 200 status code.&lt;/p&gt;

&lt;p&gt;There are already a lot of posts explaining how to patch this while waiting for an official release. But, if your main issue is about the "redirect on log out" not working, then you can easily fix this.&lt;/p&gt;

&lt;p&gt;Instead of calling &lt;code&gt;destroy_user_session_path&lt;/code&gt; in a &lt;code&gt;link_to&lt;/code&gt;, call it inside of a &lt;code&gt;button_to&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is the full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= button_to(
        "Log Out",
        destroy_user_session_path,
        method: :delete
      ) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Voilà! This simple hack enables your users to be redirected to the root_path of your app in seconds.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>tutorial</category>
      <category>devise</category>
      <category>programming</category>
    </item>
    <item>
      <title>Rails, Popper, Tailwind &amp; Stimulus</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Mon, 17 Jan 2022 12:11:37 +0000</pubDate>
      <link>https://dev.to/spaquet/rails-popper-tailwind-stimulus-1koi</link>
      <guid>https://dev.to/spaquet/rails-popper-tailwind-stimulus-1koi</guid>
      <description>&lt;p&gt;Popper is a javascript positioning engine to speed up the development of popovers and tooltips.&lt;/p&gt;

&lt;p&gt;More information about it can be found &lt;a href="https://popper.js.org" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rails 7&lt;/li&gt;
&lt;li&gt;Stimulus 2&lt;/li&gt;
&lt;li&gt;esbuild / jsbuild&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;rails new project_name --css=tailwind --javascript=esbuild&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: add popper to the project
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @popperjs/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step2: create a stimulus controller
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g stimulus popper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the &lt;code&gt;popper_controller.js&lt;/code&gt; and perform the following edits:&lt;/p&gt;

&lt;p&gt;Add at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPopper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@popperjs/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ytqq1pvdxxit6ihzhk3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ytqq1pvdxxit6ihzhk3.png" alt="Image description" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Popper instance is instantiated in the &lt;code&gt;connect()&lt;/code&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a new Popper instance&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPopper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elementTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;placementValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;modifiers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the event listeners are not added to the target or element from within the stimulus controller. As written in &lt;a href="https://www.betterstimulus.com" rel="noopener noreferrer"&gt;Better Stimulus&lt;/a&gt; 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 &lt;code&gt;data-action&lt;/code&gt; tag as explained below.&lt;/p&gt;

&lt;p&gt;Let's create the &lt;code&gt;show&lt;/code&gt; and &lt;code&gt;hide&lt;/code&gt; methods as well as the &lt;code&gt;disconnect&lt;/code&gt; one that us used to remove the popper instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// We need to tell Popper to update the tooltip position&lt;/span&gt;
    &lt;span class="c1"&gt;// after we show the tooltip, otherwise it will be incorrect&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Destroy the Popper instance&lt;/span&gt;
  &lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;At this point, the &lt;code&gt;popper_controller.js&lt;/code&gt; file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@hotwired/stimulus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPopper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@popperjs/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Connects to data-controller="popper"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tooltip&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a new Popper instance&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPopper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elementTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;placementValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;modifiers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// We need to tell Popper to update the tooltip position&lt;/span&gt;
    &lt;span class="c1"&gt;// after we show the tooltip, otherwise it will be incorrect&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltipTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Destroy the Popper instance&lt;/span&gt;
  &lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;popperInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Let's get stylish!
&lt;/h1&gt;

&lt;p&gt;We can use the one provided by the popper team as an example on their website&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#tooltip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#arrow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nf"&gt;#arrow&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#arrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#arrow&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;#tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-popper-placement&lt;/span&gt;&lt;span class="o"&gt;^=&lt;/span&gt;&lt;span class="s1"&gt;"top"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;#arrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-popper-placement&lt;/span&gt;&lt;span class="o"&gt;^=&lt;/span&gt;&lt;span class="s1"&gt;"bottom"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;#arrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-popper-placement&lt;/span&gt;&lt;span class="o"&gt;^=&lt;/span&gt;&lt;span class="s1"&gt;"left"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;#arrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-popper-placement&lt;/span&gt;&lt;span class="o"&gt;^=&lt;/span&gt;&lt;span class="s1"&gt;"right"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;#arrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#tooltip&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-show&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Saved it in &lt;code&gt;app/assets/stylesheets/popper.css&lt;/code&gt; and import it at the top of &lt;code&gt;app/assets/stylesheets/application.tailwind.css&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"popper.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* Tailwind CSS */&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's now time to work on the frontend of the project!&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Let's create a button
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-controller=&lt;/span&gt;&lt;span class="s"&gt;"popper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;data-popper-target=&lt;/span&gt;&lt;span class="s"&gt;"element"&lt;/span&gt; &lt;span class="na"&gt;data-action=&lt;/span&gt;&lt;span class="s"&gt;"mouseenter-&amp;gt;popper#show mouseleave-&amp;gt;popper#hide"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-500 text-blue-100 px-3 py-2 rounded-xl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Click me
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tooltip"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tooltip"&lt;/span&gt; &lt;span class="na"&gt;data-popper-target=&lt;/span&gt;&lt;span class="s"&gt;"tooltip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         My tooltip
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"arrow"&lt;/span&gt; &lt;span class="na"&gt;data-popper-arrow&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You can add more actions or adapt to your needs. For example, you can have &lt;code&gt;data-action="click-&amp;gt;popper#show"&lt;/code&gt; to open a popover when a user click on a certain element.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Enjoy
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7wossn29907vmiz6vsh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7wossn29907vmiz6vsh.png" alt="Image description" width="188" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>stimulus</category>
      <category>javascript</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Wrapping up 2021</title>
      <dc:creator>Stephane Paquet</dc:creator>
      <pubDate>Thu, 23 Dec 2021 04:24:01 +0000</pubDate>
      <link>https://dev.to/spaquet/wrapping-up-2021-55f3</link>
      <guid>https://dev.to/spaquet/wrapping-up-2021-55f3</guid>
      <description>&lt;h1&gt;
  
  
  Wrapping up the year with new tools for a great start in 2022.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://fig.sh" rel="noopener noreferrer"&gt;Fig&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Definitely the tool I cannot live without anymore. Its capacity to understand or simply list the options when typing CLI is fabulous and help you save a lot of time. Yes there are a lot of completion tools available, but Fig is clearly outsmarting its competitors by its speed, accuracy, flexibility and UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://tabby.sh/" rel="noopener noreferrer"&gt;Tabby&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I have to admit that I was a bit bored using iTerm2. It was great but quite massive and resource hungry. So, during most of 2021 I’ve been relying on the OS X de facto Terminal (or the one in VSCode).&lt;br&gt;
That was true till I stumbled upon Tabby. Its UI and how you can layout the different windows inside it are making it a very promising alternative to the existing terminals.&lt;br&gt;
My only regret at the time being is that Tabby is not yet supported by Fig, but that should be quickly addressed by the Fig team 😁&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://copilot.github.com/" rel="noopener noreferrer"&gt;Github Copilot&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Always on since I’ve been granted early access to it.&lt;br&gt;
Yes, some suggestions are quite out of the blue, but I appreciate it’s great help in maintaining style in my code and making smart code suggestion that I would not have come up with.&lt;br&gt;
It also greatly helps when you have to write very repetitive test cases or when working on some initialization routines.&lt;/p&gt;

&lt;p&gt;What about you? Share you comments and thoughts below.&lt;/p&gt;

&lt;p&gt;Original article was published &lt;a href="https://medium.com/@spaquet/2021-wrapped-76f04778b89c" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>productivity</category>
      <category>efficiency</category>
    </item>
  </channel>
</rss>
