<?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>Forem: isarisariver</title>
    <description>The latest articles on Forem by isarisariver (@isarisariver).</description>
    <link>https://forem.com/isarisariver</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%2F496346%2Fa79e1b38-196b-4545-a6a5-ba21593245ed.png</url>
      <title>Forem: isarisariver</title>
      <link>https://forem.com/isarisariver</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/isarisariver"/>
    <language>en</language>
    <item>
      <title>Why you should have a side project</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Tue, 09 Mar 2021 06:03:15 +0000</pubDate>
      <link>https://forem.com/isarisariver/why-you-should-have-a-side-project-100l</link>
      <guid>https://forem.com/isarisariver/why-you-should-have-a-side-project-100l</guid>
      <description>&lt;h2&gt;
  
  
  What is a side project?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;side project&lt;/strong&gt; is something that you are working on aside from your main objective or job. As a developer, it usually means you are coding in your personal time outside of your main job. The goal of a side-project is often to make a living, but there are many more benefits of side projects other than making money.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Working on something will help you come up with new ideas&lt;/li&gt;
&lt;li&gt;The best way to learn something new is to take the plunge and use it in real-life examples&lt;/li&gt;
&lt;li&gt;They help you become better at what you are doing&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Working on something will help you come up with new ideas
&lt;/h1&gt;

&lt;p&gt;Ideas don’t come just from thin air. They come from inspiration. That’s why methods like &lt;a href="https://www.merriam-webster.com/dictionary/brainstorming" rel="noopener noreferrer"&gt;brainstorming&lt;/a&gt; are so powerful because they involve creating many ideas in a short period of time. Working on a side project is like an idea generator. For example, the idea for &lt;a href="https://hackernoon.com/how-a-week-long-project-took-me-to-2-on-product-hunt-and-the-front-page-of-hacker-news-2ir3y16" rel="noopener noreferrer"&gt;oneword.domains&lt;/a&gt;  was born while trying to find a good name for a side project. I started working on &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;Cow Pilot&lt;/a&gt; while trying to make sense of my to-do list for another project.&lt;/p&gt;

&lt;p&gt;When you work on a side project, you will face a lot of problems. Often these problems lead to the “What if there was a tool for that?” questions that give you the idea for your next project.&lt;/p&gt;

&lt;h1&gt;
  
  
  The best way to learn something new is to take the plunge and use it in real-life examples
&lt;/h1&gt;

&lt;p&gt;Courses are great to learn the basics of new technology or programming language. But they can only teach you so much. The best way to learn something is to actually use it. Build something of your own with it. &lt;/p&gt;

&lt;p&gt;Want to learn React and love cooking? Build an online cookbook with your favorite recipes.  Look at other recipe sites for inspiration. &lt;/p&gt;

&lt;h1&gt;
  
  
  They help you become better at what you are doing
&lt;/h1&gt;

&lt;p&gt;It takes a lot of work to get good at something. Photographer Henri Cartier-Bresson said, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Your first 10,000 photographs are your worst.”. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Malcolm Gladwell wrote a whole book about the &lt;a href="https://en.wikipedia.org/wiki/Outliers_%28book%29" rel="noopener noreferrer"&gt;“10.000 hour rule”&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Side projects are a great way to hone your skills and become better at what you do. When you are still new, it can be hard to think about what to build with a limited set of skills. But your skills will grow while you are working on it and no matter where you are when you start, you will improve while you are creating it and soon you will wonder why you ever had any doubts about it. &lt;/p&gt;

&lt;p&gt;Projects can also evolve over time to match your skills. Let’s go back to the online cookbook with your favorite recipes. After you have built the cookbook and added a few recipes, you have the idea to build a user interface to add recipes within the app rather than in your code. You build it and when that is done you want to have more recipes, so you look for an API that serves recipes and includes them in your app. Then you want to share it with others, so you add authentication and let other people add recipes and comment on others.&lt;/p&gt;

&lt;p&gt;In the beginning, it might have been scary to build an app with all these functionalities, but by building it step-by-step matching our progress it has grown organically and you didn’t even have to think about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this article, we talked about how side projects are a great way to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate new ideas&lt;/li&gt;
&lt;li&gt;learn something new &lt;/li&gt;
&lt;li&gt;improve your skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t beat yourself up if you don’t know what your side project should be. Just pick a topic you are passionate about and start building.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>programming</category>
    </item>
    <item>
      <title>What I Learned in 120 Days of Indie Hacking</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Wed, 03 Mar 2021 04:53:23 +0000</pubDate>
      <link>https://forem.com/isarisariver/what-i-learned-in-120-days-of-indie-hacking-2554</link>
      <guid>https://forem.com/isarisariver/what-i-learned-in-120-days-of-indie-hacking-2554</guid>
      <description>&lt;p&gt;Hi Devs, long time no see.&lt;/p&gt;

&lt;p&gt;Around 120 days ago I started my journey as an indie hacker. I started building &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;Cow Pilot&lt;/a&gt;, a task management app where every task has a due date. Since then I have learned a lot about coding and met a lot of great people.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;find your schedule and work on it every day&lt;/li&gt;
&lt;li&gt;talk to users, their feedback is invaluable&lt;/li&gt;
&lt;li&gt;maintain your existing codebase, don't only add new features&lt;/li&gt;
&lt;li&gt;plan new features properly&lt;/li&gt;
&lt;li&gt;there is a great community of indie hackers online&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Work on it Every Day
&lt;/h1&gt;

&lt;p&gt;Building a product takes a lot of time and work. But if you want to succeed in building a product, you don't need to have a lot of spare time. All you need is discipline and a good schedule. I have a full-time job and two young children. The only time I can work on my project is when they sleep. That's either after they go to bed or before they wake up.&lt;/p&gt;

&lt;p&gt;I used to work in the evening. But often I did not accomplish much, because I was too tired after a long day. Nowadays I wake up at 5 AM before everybody else. That gives me up to 2-3 hours to work on my projects. I am refreshed in the morning and cannot wait to get started. This time is much more productive than in the evening.&lt;/p&gt;

&lt;p&gt;You can build a product even if you only have 1 hour or 30 minutes every day. The time compounds and before you know it you have written thousands of lines of code or written dozens of blog articles.&lt;/p&gt;

&lt;p&gt;As Benjamin Franklin said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Little strokes fell great oaks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Talk to Your Users
&lt;/h1&gt;

&lt;p&gt;When I started building Cow Pilot, I shared the initial version on &lt;a href="https://dev.to/isarisariver/i-just-published-my-new-side-project-27kl"&gt;Dev.to&lt;/a&gt;. I received a lot of helpful comments. You mentioned things I had not considered or bugs that I had not noticed.&lt;/p&gt;

&lt;p&gt;The same thing happened after I released the app on &lt;a href="https://www.producthunt.com/posts/cow-pilot" rel="noopener noreferrer"&gt;Producthunt&lt;/a&gt;. The most valuable feedback came from users that told me that they like the idea, but would not switch from their current app (yet).&lt;/p&gt;

&lt;p&gt;I have made it a practice since then to send an email to a random user from time to time. I just write something like&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi, this is Marian. I hope you're having a great day. I just wanted to check in and see if you have any questions or remarks about Cow Pilot. Thank you so much for using my app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It took me a long time to send the first email. &lt;/p&gt;

&lt;p&gt;I felt so awkward writing it. I was so worried about finding the right words. But what was the worst that could happen? In the end, I just sent it. Everything is a learning experience. After all, when was the last time you wondered why a newsletter or email has strange wording? The second email was much easier than the first one.&lt;/p&gt;

&lt;h1&gt;
  
  
  It's important to maintain your existing codebase, not only to add new features
&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%2Fax9kok46nh3vfbkqntku.gif" 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%2Fax9kok46nh3vfbkqntku.gif" alt="a man trying to explain his whiteboard" width="480" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have written a lot of code in this project. Sometimes it takes me a while to understand what I have written or I ask myself "Why did I make it so complicated?". I guess it means that I am growing as a developer.&lt;/p&gt;

&lt;p&gt;Nowadays I try to comment my code as much as possible. I write down in plain English what I want to accomplish and what I had to consider at the time of writing. It helps me a lot when I come back a few weeks later.&lt;/p&gt;

&lt;p&gt;It is easy to neglect proper formatting and commenting when trying to build as fast as possible. Releasing a new feature is more important to me than having a perfect folder structure. After all, I am the only person working on it. But as the codebase grows bigger it also becomes harder to find what I'm looking for. It is the perfect time to think about improving the codebase and make it more maintainable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you are unable to understand the cause of a problem, it is impossible to solve it.” – Naoto Kan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Plan new features properly
&lt;/h1&gt;

&lt;p&gt;Every new feature has countless angles, how it can affect existing code. I believe that too much planning can negatively affect your productivity, but so can not enough planning.&lt;/p&gt;

&lt;p&gt;Let's look at an example: In February I added &lt;a href="https://www.cow-pilot.io/blog/introducing-projects-for-cow-pilot" rel="noopener noreferrer"&gt;Projects&lt;/a&gt; to Cow Pilot.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was on my list:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;add selector in sidebar and in task modal&lt;/li&gt;
&lt;li&gt;add new field in task on database&lt;/li&gt;
&lt;li&gt;add new routes in backend to handle CRUD (create, read, -update, delete)&lt;/li&gt;
&lt;li&gt;handle CRUD in frontend&lt;/li&gt;
&lt;li&gt;handling tasks in bulk edit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I did not plan in advance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;handling tasks without projects&lt;/li&gt;
&lt;li&gt;removing a task from a project&lt;/li&gt;
&lt;li&gt;selecting multiple tasks to move them to a project, but some of them already are in that project&lt;/li&gt;
&lt;li&gt;handling "undo" for one task and multiple tasks&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the beginning, I did not account for "negative" actions like removing a project. This led to a back and forth of fixing and testing. I would have been faster and the code would have been cleaner if I had taken it into account from the beginning.&lt;/p&gt;

&lt;h1&gt;
  
  
  The indie hackers community
&lt;/h1&gt;

&lt;p&gt;There is a big community of indie hackers out there. Everybody is very supportive and they are very active on Twitter. There are also dedicated communities like &lt;a href="https://getmakerlog.com/" rel="noopener noreferrer"&gt;Makerlog&lt;/a&gt; and &lt;a href="https://www.indiehackers.com/" rel="noopener noreferrer"&gt;IndieHackers.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have met new interesting people and friends. A lot of them build in public, which means sharing their ongoing process of building their product. There is a lot to learn from their insights. The most valuable lessons come from mistakes they have made.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;It has just been four months since I started working on this project. I have learned more in these four months than I could ever learn from any course or bootcamp. I have come very far already when I compare my MVP to where I am now. But I am far from finished.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>productivity</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>A repository with more than 250 web development resources</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Sat, 09 Jan 2021 11:35:47 +0000</pubDate>
      <link>https://forem.com/isarisariver/a-repository-with-more-than-250-web-development-resources-50d7</link>
      <guid>https://forem.com/isarisariver/a-repository-with-more-than-250-web-development-resources-50d7</guid>
      <description>&lt;p&gt;Hi, I'm Marian. I compiled a list with all my resources that have helped me in my web development projects in the last 2 years. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/isarisariver/webdev" rel="noopener noreferrer"&gt;https://github.com/isarisariver/webdev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am currently working on a due-date driven task management app called &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;Cow Pilot&lt;/a&gt; and wanted to have a single location for all my links and snippets rather than having it scattered across multiple apps and browsers.&lt;/p&gt;

&lt;p&gt;I divided it into the following categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;General&lt;/li&gt;
&lt;li&gt;Html&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;Node JS / Express JS&lt;/li&gt;
&lt;li&gt;Heroku&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Libraries&lt;/li&gt;
&lt;li&gt;Landing Page&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;li&gt;Git / GitHub&lt;/li&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;Security, CORS and Authentication&lt;/li&gt;
&lt;li&gt;Auth0&lt;/li&gt;
&lt;li&gt;Videos&lt;/li&gt;
&lt;li&gt;Snippets and Commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the resources are aimed at (advanced) beginners I guess, since I am a noob myself. The resources range from Stack Overflow answers over long form blog posts to official references.&lt;/p&gt;

&lt;p&gt;I hope it's useful. Feel free to share it.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Marian&lt;/p&gt;

</description>
      <category>react</category>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I created my app from idea to public beta in one month</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Fri, 11 Dec 2020 19:51:55 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-i-created-my-app-from-idea-to-public-beta-in-one-month-25h2</link>
      <guid>https://forem.com/isarisariver/how-i-created-my-app-from-idea-to-public-beta-in-one-month-25h2</guid>
      <description>&lt;p&gt;Hi, I'm &lt;a href="https://twitter.com/isarisariver" rel="noopener noreferrer"&gt;Marian&lt;/a&gt; and I'm the creator of &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;cow-pilot.io&lt;/a&gt;, a due date driven to-do list app written in ReactJS. In this post I want to share my journey from idea to launch of the public beta.&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%2Fft6lb7vs6s1lcm4uyoz5.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%2Fft6lb7vs6s1lcm4uyoz5.png" alt="Screenshot 2020-12-11 at 19.01.58.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From Idea to MVP
&lt;/h2&gt;

&lt;p&gt;There are lots of task management apps out there, Todoist being one of my favourites. My problem with most of them is that they are either too basic or have so many features that they become overwhelming and it's hard to find the task I'm looking for.&lt;/p&gt;

&lt;p&gt;So I decided to build my own app. As a challenge I made a plan to &lt;strong&gt;finish the MVP within a week&lt;/strong&gt;. With this approach I made sure that I only add what is absolutely necessary and don't fall into the trap of adding a bunch of stuff that does not really contribute to the original idea.&lt;/p&gt;

&lt;p&gt;I wanted the MVP to have the following basic features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide a fixed structure for all tasks.&lt;/li&gt;
&lt;li&gt;Don't allow more than 6 tasks for "Today", to focus on my most important tasks&lt;/li&gt;
&lt;li&gt;Drag and drop to quickly move tasks between blocks.&lt;/li&gt;
&lt;li&gt;Have a due date for all tasks automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No database, no login, just a teaser page, a demo and a signup link for the private beta. &lt;/p&gt;

&lt;p&gt;I have a full-time job, so to finish it in one week I got up a 5am every day. That gave me 2-3 hours before I had to go to work and a little time in the evening before going to bed. It was the most productive week I had in a long time and I kept up this schedule until today. Turns out waking up early can be very easy when there is a good purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharing the initial version
&lt;/h2&gt;

&lt;p&gt;After it was finished, I shared it on &lt;a href="https://news.ycombinator.com/" rel="noopener noreferrer"&gt;Hackernews&lt;/a&gt;, because I read that's where I have to go to validate an idea. I got 0 upvotes. Well, that was disappointing ...&lt;/p&gt;

&lt;p&gt;I tried again the two days later and shared it on &lt;a href="https://dev.to/isarisariver/i-just-published-my-new-side-project-27kl"&gt;Dev.to&lt;/a&gt;. This post was a great success for me. I got a lot of feedback from the community how to improve the UI, fix some bugs etc. The reactions convinced me to keep working on my app. Around 25 people signed up for the closed beta.&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%2Fagw7ob9iumdq5ftoi5ch.gif" 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%2Fagw7ob9iumdq5ftoi5ch.gif" alt="gif_today.gif" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending out invitations for the private beta
&lt;/h2&gt;

&lt;p&gt;With 25 people on the waitlist it was time to start building a database and to add login functionalities. It took me a few more days to set up the &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; server in NodeJS,  link it to a &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; cluster and implement authentication with &lt;a href="https://auth0.com/" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Once everything was finished I started sending out the invitations. I wrote a &lt;strong&gt;much too long email&lt;/strong&gt; that most of my recipients probably did not even read. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everybody hates long emails. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Out of the 25 email addresses I had, 8 did not even exist and nobody replied. In total 2 users logged in once and never again. Another disappointment... In hindsight I would have written that invitation differently, but the response probably wouldn't have been much better. &lt;/p&gt;

&lt;h2&gt;
  
  
  Launching on Product Hunt
&lt;/h2&gt;

&lt;p&gt;Even though I experienced another setback, I kept working on my app. I started using it to track my own project, which gave me a lot of ideas how to improve it further. After almost one month of working on it a couple of hours every day I did not have much feedback except from my family and the Dev.to community. &lt;/p&gt;

&lt;p&gt;So I decided to start the public beta and launch it on &lt;a href="https://www.producthunt.com/posts/cow-pilot" rel="noopener noreferrer"&gt;Product Hunt&lt;/a&gt;. 😀 If again I get zero feedback, maybe that means there are not enough people who are interested in a task management app like this.&lt;/p&gt;

&lt;p&gt;I read a few guides what to do when preparing to launch on Product Hunt.&lt;/p&gt;

&lt;p&gt;There's of course &lt;a href="https://blog.producthunt.com/how-to-launch-on-product-hunt-7c1843e06399" rel="noopener noreferrer"&gt;the official guide&lt;/a&gt;, but also posts &lt;a href="https://www.reddit.com/r/Entrepreneur/comments/gfs7mp/how_i_made_2k_in_24_hours_on_the_launch_day/?ref=hackernoon.com" rel="noopener noreferrer"&gt;like this one&lt;/a&gt; on Reddit that helped me a lot. &lt;/p&gt;

&lt;p&gt;Following the advice &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I launched on a Saturday and &lt;/li&gt;
&lt;li&gt;at midnight PST (which conveniently is 9am in Germany 😀). &lt;/li&gt;
&lt;li&gt;I prepared a few GIF's for the listing, &lt;/li&gt;
&lt;li&gt;wrote a first comment to welcome users and explain why I built this app. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was in the top 5 for while, but in the end came in 7th. I got around 500 visitors and 50 new users on Saturday. The traffic I received from Product Hunt did not go down until the middle of this week and I have already received very positive feedback and interesting questions from some of the users. This time around they are actually using it 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;One week after starting the public beta I have around 80 users. I hope I can get more feedback, so that I can further improve the app. After making sure that the app is stable I want to start working on desktop and mobile apps.&lt;/p&gt;

&lt;p&gt;While it is not a huge overwhelming success, it is slowly growing and gaining new users. It is such a rewarding experience to see that people are actually using an app that I have built. &lt;/p&gt;

&lt;p&gt;I hope this little journey can help you staying motivated with your own side project. If you have any questions, just let me know here or on &lt;a href="https://twitter.com/isarisariver" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>react</category>
      <category>showdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>How do you structure your React projects?</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Mon, 30 Nov 2020 13:34:12 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-do-you-structure-your-react-projects-4om2</link>
      <guid>https://forem.com/isarisariver/how-do-you-structure-your-react-projects-4om2</guid>
      <description>&lt;p&gt;I don't really have a structure when it comes to my projects. I guess it doesn't really matter as long as I am the only one working on it. &lt;/p&gt;

&lt;p&gt;I usually start by putting everything in 1 file. When I feel like it gets too big, I create a second file. When I get too many files, I create folders like "assets" for images or "utils" for reusable functions.&lt;/p&gt;

&lt;p&gt;This is what &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;my current project&lt;/a&gt; looks like.&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%2Fi%2Fszu8dowoqf1y8rirlbs8.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%2Fi%2Fszu8dowoqf1y8rirlbs8.png" alt="Alt Text" width="718" height="1412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do you guys organise your projects? Any tips for a self-taught noob like me? :)&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
      <category>react</category>
    </item>
    <item>
      <title>How to create separate Signup and Login screens with Auth0</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Sat, 28 Nov 2020 07:40:44 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-to-create-separate-signup-and-login-screens-with-auth0-195m</link>
      <guid>https://forem.com/isarisariver/how-to-create-separate-signup-and-login-screens-with-auth0-195m</guid>
      <description>&lt;p&gt;Hi guys. Today I wanted to quickly share how to create separate sign up and login screens in Auth0's &lt;a href="https://auth0.com/docs/universal-login" rel="noopener noreferrer"&gt;universal login&lt;/a&gt;, as it is not directly mentioned in their otherwise great documentation. &lt;/p&gt;

&lt;p&gt;At the moment it is only possible to go &lt;a href="https://auth0.com/docs/universal-login/new-experience#signup" rel="noopener noreferrer"&gt;directly to the signup&lt;/a&gt; screen with the "new experience", but since it lacks customization, I did not want to use it for &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;my own project&lt;/a&gt;. I assume you already have an integration and are just looking for a way to separate signup and login, so I will not go much into detail about the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go directly to the signup page
&lt;/h2&gt;

&lt;p&gt;Usually signup looks like this. The widget shows both login and signup and the user has to choose.&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%2Fi%2Fpisfurhqawowhnhqbf64.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%2Fi%2Fpisfurhqawowhnhqbf64.png" alt="Alt Text" width="300" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To show the signup first, we have to provide a parameter to the &lt;code&gt;loginWithRedirect&lt;/code&gt; function that is calling the screen, for example '{ mode: "signUp" }'. This parameter can then be read in the Lock widget with &lt;code&gt;config.extraParams&lt;/code&gt;&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="cm"&gt;/* Example with React*/&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Signup&lt;/span&gt; 
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loginWithRedirect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;signUp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Sign&lt;/span&gt; &lt;span class="nx"&gt;Up&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Signup&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customize Login Page
&lt;/h2&gt;

&lt;p&gt;Now that we have a separate button for signup, the next step is to go to "Universal Login" in the dashboard and activate the "customize login page" option.&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%2Fi%2Fizxz1pfbnrtvmwh9yxh4.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%2Fi%2Fizxz1pfbnrtvmwh9yxh4.png" alt="Alt Text" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This opens the Lock widget for editing. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lock is an embeddable login form that can be configured to your needs and is recommended for use in single-page apps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lock has a lot of &lt;a href="https://auth0.com/docs/libraries/lock/lock-configuration" rel="noopener noreferrer"&gt;configuration options&lt;/a&gt;, but we are mostly interested in the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;config.extraParams&lt;/li&gt;
&lt;li&gt;initialScreen&lt;/li&gt;
&lt;li&gt;allowLogin&lt;/li&gt;
&lt;li&gt;allowSignup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;config.extraParams&lt;/code&gt; is already configured out of the box and we can use it to read the parameter that we provided in &lt;code&gt;loginWithRedirect&lt;/code&gt;.&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="c1"&gt;// Decode utf8 characters properly&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@@config@@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraParams&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you put a &lt;code&gt;console.log&lt;/code&gt; in the widget, you can see all the parameters that are passed when the widget is open. In my case I send "login_hint" for signup.&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%2Fi%2Fka2fhy30njhhptw54p4u.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%2Fi%2Fka2fhy30njhhptw54p4u.png" alt="Alt Text" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The actual configuration of the widget starts at line 38 and starts with &lt;code&gt;var lock = new Auth0Lock(config.clientID, config.auth0Domain,&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;We add our 3 lines of code after that initialization&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose initial screen
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;initialScreen&lt;/code&gt; lets us choose, which screen to show first when using &lt;code&gt;loginWithRedirect&lt;/code&gt;. We want to show signup when the parameter we gave earlier is present and show login when it is not. Be careful to use &lt;a href="https://en.wikipedia.org/wiki/Camel_case" rel="noopener noreferrer"&gt;camelcase&lt;/a&gt; for &lt;code&gt;signUp&lt;/code&gt;, otherwise it will not work&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="nx"&gt;intialScreen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&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="s1"&gt;signUp&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;h2&gt;
  
  
  Either login or signup
&lt;/h2&gt;

&lt;p&gt;To show only one of the two screens at any given time, we can use the &lt;code&gt;allowLogin&lt;/code&gt; and &lt;code&gt;allowSignup&lt;/code&gt; options. If the extraParams that was given is present, we want to show only signup, otherwise we show only login.&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="nx"&gt;allowLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
    &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;allowSignUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
    &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. Now we have two separate screens for signup and login. &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%2Fi%2Fnm7oyxz9231599q60alg.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%2Fi%2Fnm7oyxz9231599q60alg.png" alt="Alt Text" width="600" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions, please let me know.&lt;/p&gt;

</description>
      <category>auth0</category>
      <category>tutorial</category>
      <category>howto</category>
    </item>
    <item>
      <title>I just published my new side project</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Tue, 17 Nov 2020 04:54:56 +0000</pubDate>
      <link>https://forem.com/isarisariver/i-just-published-my-new-side-project-27kl</link>
      <guid>https://forem.com/isarisariver/i-just-published-my-new-side-project-27kl</guid>
      <description>&lt;p&gt;Hi guys, I just published my new side project and I'd love to have some feedback 😊.  I built it in 5 days, focussing only on the essentials. &lt;/p&gt;

&lt;p&gt;I had a breeze making this and getting it ready for a demo in the shortest possible amount of time. This is the link: &lt;a href="https://www.cow-pilot.io/" rel="noopener noreferrer"&gt;https://www.cow-pilot.io/&lt;/a&gt;. I would really love to hear what you think about it. &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%2Fxbs637dh2wflm28p63mk.gif" 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%2Fxbs637dh2wflm28p63mk.gif" alt="a cat typing on a computer" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is built with React, hosted on Heroku. It's already a win for me, because in the process I learned about &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled components&lt;/a&gt;, a library that makes styling much, much easier than plain CSS. &lt;/p&gt;

&lt;p&gt;I also learned about &lt;a href="https://github.com/atlassian/react-beautiful-dnd" rel="noopener noreferrer"&gt;react-beautiful-dnd&lt;/a&gt;, which is an awesome library for drag and drop by the guys who made Trello. They have an eggcellent course on &lt;a href="https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd" rel="noopener noreferrer"&gt;egghead.io&lt;/a&gt; to help learn it. I don't like video courses much usually, but this one is really well made and helped build the foundation of my app.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>showdev</category>
      <category>react</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>How to create a README.md for your Github profile</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Sun, 15 Nov 2020 19:40:27 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-to-create-a-readme-md-for-your-github-profile-5207</link>
      <guid>https://forem.com/isarisariver/how-to-create-a-readme-md-for-your-github-profile-5207</guid>
      <description>&lt;p&gt;The other day I came across a Github profile with a big flashy username/README.md on the profile screen. I had no idea this is possible, so I checked how to do it and now I have one, too. &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%2Fi%2Fqbpllgfdbofx2h41efv1.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%2Fi%2Fqbpllgfdbofx2h41efv1.png" alt="Alt Text" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create the profile README.md
&lt;/h2&gt;

&lt;p&gt;To create the profile readme, simply create a repository with the same name as your username. You will be greeted immediately with this message:&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%2Fi%2F9mop5bsa31kuvkv9jrf7.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%2Fi%2F9mop5bsa31kuvkv9jrf7.png" alt="Alt Text" width="759" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to edit the profile README.md
&lt;/h2&gt;

&lt;p&gt;Go to the profile and start editing the README. It works like with any other README.md on Github. To use images and gifs, upload them to your &lt;em&gt;secret&lt;/em&gt; repository and reference them in the README.&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%2Fi%2Ffqzalovdhd2nwum3j7uf.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%2Fi%2Ffqzalovdhd2nwum3j7uf.png" alt="Alt Text" width="706" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it. Have a great start of the week! 🦄&lt;/p&gt;

</description>
      <category>github</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How to Create a Custom Confirm Box with React</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Sun, 15 Nov 2020 06:09:57 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-to-create-a-custom-confirm-box-with-react-754</link>
      <guid>https://forem.com/isarisariver/how-to-create-a-custom-confirm-box-with-react-754</guid>
      <description>&lt;p&gt;Hi, I'm Marian and I just released my new side project called &lt;a href="https://www.cow-pilot.io" rel="noopener noreferrer"&gt;Cow Pilot&lt;/a&gt;. It's a to-do list app, but you can only add 6 tasks. &lt;/p&gt;

&lt;p&gt;Today I wanted to share how I created a custom confirm box, since the standard ones look kinda boring and different in every browser.&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%2Fi%2F6pwis4yywwihqqmjnlwl.gif" 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%2Fi%2F6pwis4yywwihqqmjnlwl.gif" alt="Alt Text" width="578" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, the same confirm box looks like this in Firefox &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%2Fi%2F16nnr376fwfh08qchhx0.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%2Fi%2F16nnr376fwfh08qchhx0.png" alt="A confirm box in Firefox" width="267" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and like this in Chrome &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%2Fi%2Ffc16dp3smjmqte23wagj.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%2Fi%2Ffc16dp3smjmqte23wagj.png" alt="A confirm box in Chrome" width="451" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not pretty. It can be set up 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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirmBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Do you really want to delete this Crumb?&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;confirmBox&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;handleDeleteCrumb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bookmark&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="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The custom variant works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add an opaque full screen background to the DOM&lt;/li&gt;
&lt;li&gt;Below that, add a &lt;code&gt;div&lt;/code&gt; that acts as the confirm box container&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;div&lt;/code&gt; add a text and the &lt;em&gt;Cancel&lt;/em&gt; and &lt;em&gt;OK&lt;/em&gt; buttons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In normal state, the background and the container both have the property &lt;code&gt;display: none&lt;/code&gt;, which means they are not visible on the screen and other than &lt;code&gt;visibility: hidden&lt;/code&gt; don't take up any space. &lt;br&gt;
We make them visible by clicking on a button, for example in my case &lt;em&gt;"Delete Task"&lt;/em&gt;, which calls a function that changes &lt;code&gt;display: none&lt;/code&gt; to &lt;code&gt;display: flex&lt;/code&gt; &lt;em&gt;(or instead of anything else that is not &lt;code&gt;none&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are several ways to make them visible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;display.querySelector(".container").style.display =&lt;/code&gt;  to unhide and hide the box&lt;/li&gt;
&lt;li&gt;use useState to add and remove a class with property &lt;code&gt;display: none&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;use inline styles and toggle the &lt;code&gt;display: none&lt;/code&gt; property with useState&lt;/li&gt;
&lt;li&gt;use &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled components&lt;/a&gt;, a  library I have started using recently. We pass props to the styled component and use it to toggle between &lt;code&gt;display: flex&lt;/code&gt; and &lt;code&gt;display: none&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post I will focus on the first variant. If you are interested I can make a follow-up for the other ways as well, just let me know in the comments.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the Elements
&lt;/h2&gt;

&lt;p&gt;First, let's create the background. I'm adding it to be able to close the box by clicking anywhere outside of it. I also disable scrolling with &lt;code&gt;overflow:hidden&lt;/code&gt; while the background is visible. I like to make it black and 50% opaque to accentuate the confirm box, but you can also make it completely opaque.&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="cm"&gt;/* The JSX */&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; 
    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirm-bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleConfirmationBox&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* The CSS */&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bg&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="nx"&gt;fixed&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="nx"&gt;none&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="mi"&gt;0&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="mi"&gt;0&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="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&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="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;202020&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.55&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* disable scrolling*/&lt;/span&gt;
  &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* higher than all other items, but lower than 
    the confirm box*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we add the container. I use &lt;code&gt;position: fixed&lt;/code&gt; to place it close to the &lt;em&gt;delete&lt;/em&gt; button. In our component we have to add it right before the background, otherwise it will appear behind it on the screen.&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="cm"&gt;/* The JSX */&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmation-text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;really&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cancel-button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
        &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleConfirmationBox&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Cancel&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmation-button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleDeleteTask&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Delete&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; 
    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirm-bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleConfirmationBox&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

&lt;span class="cm"&gt;/* The CSS */&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&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="nx"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&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="nx"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;f37736&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="mi"&gt;230&lt;/span&gt;&lt;span class="nx"&gt;px&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="mi"&gt;75&lt;/span&gt;&lt;span class="o"&gt;%&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="mi"&gt;50&lt;/span&gt;&lt;span class="o"&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="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="nx"&gt;rem&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="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Higher than the z-index of the background */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;confirmation&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;text&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="nx"&gt;flex&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="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="nx"&gt;rem&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="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;container&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="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;between&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="nx"&gt;confirmation&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&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="nx"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;cc0000&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="nx"&gt;white&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="mf"&gt;0.7&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt; &lt;span class="mf"&gt;1.4&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;rem&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="nx"&gt;cancel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;999999&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="nx"&gt;confirmation&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pointer&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="nx"&gt;cancel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;b2b2b2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pointer&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;h2&gt;
  
  
  Toggle the elements
&lt;/h2&gt;

&lt;p&gt;Now the elements are set up and we can work on showing them and hiding them again. &lt;/p&gt;

&lt;p&gt;First we need the button that triggers the confirmation check. It can be anywhere in the component. On click, the button calls a function that changes the &lt;code&gt;display&lt;/code&gt; property .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* JSX */&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; 
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"delete-button"&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;handleConfirmationBox&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Delete&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of &lt;code&gt;handleConfirmationBox&lt;/code&gt; we will use a &lt;code&gt;state&lt;/code&gt; to check, if we should show or hide the confirmation check. We use a boolean value and set the default to &lt;em&gt;false&lt;/em&gt;. In the &lt;em&gt;handleConfirmationBox&lt;/em&gt; function, we assign &lt;em&gt;false&lt;/em&gt; to hiding the popup. &lt;/p&gt;

&lt;p&gt;We call this function when we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;click on the &lt;em&gt;delete task&lt;/em&gt; button&lt;/li&gt;
&lt;li&gt;click on the &lt;em&gt;cancel&lt;/em&gt; button&lt;/li&gt;
&lt;li&gt;click anywhere outside the box, while it is visible
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* define the state */&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;useState&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;delTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDelTask&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;/* if delTask is false, change the display properties of our 
 * two elements and change delTask to true, so that next time 
 * the function is called, the elements are hidden again
 */&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleConfirmationBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;delTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.confirm-bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;setDelTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.confirm-bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;setDelTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;And that's it. Now the confirmation will look the same on all devices and we can customize it the way we want. Like I say, there are several ways to achieve the hide/unhide. I personally like &lt;em&gt;styled components&lt;/em&gt; because I can just pass the &lt;code&gt;delTask&lt;/code&gt; state as prop and change the &lt;code&gt;display&lt;/code&gt; property based on that.&lt;/p&gt;

&lt;p&gt;If you have any questions or if I missed something, please let me know.&lt;/p&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Creating a Context Menu for my Bookmark Manager</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Wed, 04 Nov 2020 15:32:38 +0000</pubDate>
      <link>https://forem.com/isarisariver/creating-a-context-menu-for-my-bookmark-manager-3fk2</link>
      <guid>https://forem.com/isarisariver/creating-a-context-menu-for-my-bookmark-manager-3fk2</guid>
      <description>&lt;p&gt;Today I replaced the topbar entries of my bookmark manager called &lt;a href="https://www.crumb-collector.com" rel="noopener noreferrer"&gt;Crumb Collector&lt;/a&gt; with a context menu, because they did not fit properly anymore on mobile devices. The app is written using the MERN stack, so in this post I'd like to share how I created this context menu in React.&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%2Fi%2F2v1rr3261d9zvvfg2zce.gif" 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%2Fi%2F2v1rr3261d9zvvfg2zce.gif" alt="Alt Text" width="670" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I also finally managed to properly loop the cover image GIF, but that's not the topic of this post.&lt;/em&gt;😉&lt;/p&gt;

&lt;h2&gt;
  
  
  The Requirement
&lt;/h2&gt;

&lt;p&gt;I used to have just the &lt;code&gt;Log In&lt;/code&gt; button in the top right corner, but wanted to add a few more icons, which made it too wide for mobile devices. I wanted the context menu to open when the user hovers over it and it should include important links on the site as well as links to my blog, Twitter and Dev.to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basic Setup
&lt;/h2&gt;

&lt;p&gt;The topbar is a &lt;code&gt;div&lt;/code&gt;-element with fixed position, so that it is always at the top of the screen. I am using &lt;a href="https://fontawesome.com/icons/caret-down?style=solid" rel="noopener noreferrer"&gt;FontAwesome&lt;/a&gt; for the caret icon. The &lt;code&gt;More&lt;/code&gt; entry is the container for our context menu. The menu itself is placed outside of the viewport using &lt;code&gt;position: absolute&lt;/code&gt; and &lt;code&gt;right: -10rem&lt;/code&gt; and will be made visible when we hover over &lt;code&gt;More&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I added a &lt;code&gt;transition-delay&lt;/code&gt; to &lt;code&gt;.topbar-menu&lt;/code&gt; so that it does not disappear immediately, when the mouse leaves the element that triggered the hover-effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The JSX&lt;/strong&gt;&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;div className='topbar'&amp;gt;
  &amp;lt;div className='topbar-items'&amp;gt;
    {handleDarkmode}
    &amp;lt;span className="more" &amp;gt;
      More &amp;lt;i className="fas fa-caret-down"&amp;gt;&amp;lt;/i&amp;gt;
        &amp;lt;ul className="topbar-menu"&amp;gt;
          &amp;lt;li&amp;gt;...&amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;...&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* This is the topbar, pinned to the top.*/
.topbar {
  position: fixed;
  display: flex;
  flex-direction: row;
  height: 48px;
  width: 100%;
  background-color: #252525;
  line-height: 36px;
  z-index: 2;
  top: 0;
}

/* This is the class for the topbar items.*/
.topbar-items {
  display: flex;
  margin-left: auto;
  margin-right: 2rem;
  align-items: center;
  cursor: pointer;
  color: white;
}

/* This is the context menu, placed outside of the viewport 
 */
.topbar-menu {
  position: absolute;
  right: -10rem;
  margin-top: 0.8rem;
  background-color: #1c75da;
  display: flex;
  flex-direction: column;
  transition: 0.1s;
  transition-delay: 0.3s;
  text-align: center;
  width: auto;
  border-radius: 0.3rem;
  font-weight: 700;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Displaying The Context Menu
&lt;/h2&gt;

&lt;p&gt;I want the menu to show up automatically when I hover over &lt;code&gt;More&lt;/code&gt;, so I have to add &lt;code&gt;:hover&lt;/code&gt; to the menu entry in combination with class &lt;code&gt;.topbar-menu&lt;/code&gt;. On hover, the menu will move into the viewport using &lt;code&gt;transform: translateX&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.more:hover .topbar-menu {
  transform: translateX(-11rem);
  transition: 0.1s;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styling the menu
&lt;/h2&gt;

&lt;p&gt;The first four items are just regular list-items that are styled like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The JSX&lt;/strong&gt;&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;ul className="topbar-menu"&amp;gt;
          &amp;lt;li className="dropdown"&amp;gt;
            &amp;lt;Link className='profile-link' to="/support"&amp;gt;
              Contact
            &amp;lt;/Link&amp;gt;
          &amp;lt;li&amp;gt;          
        &amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.dropdown {
  width: 140px;
  height: 2rem;
  line-height: 2rem;
  cursor: pointer;
  border-bottom: 1px solid white;
}

.profile-link {
  text-decoration: none;
  color: white;
  width: max-content;
  width: 100%;
  height: 100%;
  display: block;
  font-size: 0.9rem
}

.profile-link:hover {
  background-color: #4490E1;
  border-radius: 0.3rem;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid making the menu unnecessary long, I wanted to place the social icons all in one row. I added a second class to the list-item and changed the &lt;code&gt;display&lt;/code&gt; property to inline-flex and added &lt;code&gt;flex: 0.34&lt;/code&gt; to give each 1/3rd of the width.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The JSX&lt;/strong&gt;&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;li className="dropdown social"&amp;gt;
  &amp;lt;a className="profile-link social"
     rel="noopener nofollow noreferrer"
     href="https://dev.to/isarisariver"&amp;gt;
       &amp;lt;i className="fab fa-dev" 
          title="DEV Profile"&amp;gt;  
       &amp;lt;/i&amp;gt;
  &amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;li.dropdown.social {
  display: flex;
  justify-content: space-evenly;
}

.profile-link.social {
  display: inline-flex;
  width: auto;
  font-size: 1.2rem;
  align-items: center;
  flex: 0.34;
  justify-content: center;
  border-radius: 0.3rem;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that's it. I hope it can help you with your next project! If you have any questions, just drop me a message. 😄&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>react</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How to Determine Font Color based on a Random Background Color</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Fri, 30 Oct 2020 20:30:22 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-to-determine-font-color-based-on-a-random-background-color-8ek</link>
      <guid>https://forem.com/isarisariver/how-to-determine-font-color-based-on-a-random-background-color-8ek</guid>
      <description>&lt;p&gt;Inspired by &lt;a href="https://dev.to/dailydevtips1/vanilla-javascript-random-colours-2nnp"&gt;this great post&lt;/a&gt; by &lt;a class="mentioned-user" href="https://dev.to/dailydevtips1"&gt;@dailydevtips1&lt;/a&gt; about how to create random colors with Vanilla Javascript, I decided to write a little follow-up to make sure, the random color also has a matching font-color.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Random Background Color
&lt;/h2&gt;

&lt;p&gt;As a reminder, we are generating random hexadecimal number with this function: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Math.floor(Math.random()*10000000).toString(16)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Actually, we might as well use 16777215 as a multiplier, which is the &lt;a href="https://convertingcolors.com/decimal-color-16777215.html" rel="noopener noreferrer"&gt;maximum possible decimal for a color&lt;/a&gt; (meaning 16777215 === #FFFFFF).&lt;/p&gt;

&lt;p&gt;The result of this formula is a 6-digit hexadecimal number. Like RGB colors it consists of three parts: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first two digits represent the color red&lt;/li&gt;
&lt;li&gt;digits three and four represent the color green&lt;/li&gt;
&lt;li&gt;the last two digits represent the color blue&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Determining the Font Color
&lt;/h2&gt;

&lt;p&gt;To determine, which is the best possible font-color for a certain background, we can follow the recommended algorithm on &lt;a href="https://www.w3.org/TR/AERT/#color-contrast" rel="noopener noreferrer"&gt;www.w3.org&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Color brightness is determined by the following formula:&lt;br&gt;
((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Converting this formula to Javascript could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const red = parseInt(color.substring(0,2),16)
const green = parseInt(color.substring(2,4),16)
const blue = parseInt(color.substring(4,6),16)
const brightness = red*0.299 + green*0.587 + blue*0.114
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have an integer value for the perceived brightness of our background color. &lt;/p&gt;

&lt;p&gt;We took each color from the previously generated random color using &lt;code&gt;substring&lt;/code&gt; and converted the hexadecimal to a decimal using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt" rel="noopener noreferrer"&gt;&lt;code&gt;parseInt()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since the variable &lt;code&gt;brightness&lt;/code&gt; of our function represents the brightness of our color, we can now use it to define the font color. I found that 180 is a good threshold to switch from white to black, but it's probably best to experiment a bit.&lt;/p&gt;

&lt;p&gt;The function to set the font color could look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (brightness &amp;gt; 180) {
      return { backgroundColor: '#' + color }
    }
    else return {
      backgroundColor: '#' + color,
      color: '#ffffff'
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And my whole function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const randomColor = () =&amp;gt; {
    let color = Math.floor(Math.random()*16777215).toString(16)

    /* sometimes the returned value does not have 
     * the 6 digits needed, so we do it again until
     * it does 
     */

    while (color.length&amp;lt;6) {
      color = Math.floor(Math.random()*16777215).toString(16)
    }

    let red = parseInt(color.substring(0,2),16)
    let green = parseInt(color.substring(2,4),16)
    let blue = parseInt(color.substring(4,6),16)
    let brightness = red*0.299 + green*0.587 + blue*0.114

    /* if (red*0.299 + green*0.587 + blue*0.114) &amp;gt; 180 
     * use #000000 else use #ffffff 
     */

    if (brightness &amp;gt; 180) {
      return { backgroundColor: '#' + color }
    }
    else return {
      backgroundColor: '#' + color,
      color: '#ffffff'
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In an app it would look like this:&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%2Fi%2Frjmoyle1wqi63eudnpw9.gif" 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%2Fi%2Frjmoyle1wqi63eudnpw9.gif" alt="Alt Text" width="542" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Create a Custom Tooltip with Pure CSS</title>
      <dc:creator>isarisariver</dc:creator>
      <pubDate>Mon, 26 Oct 2020 07:48:28 +0000</pubDate>
      <link>https://forem.com/isarisariver/how-to-create-a-custom-tooltip-with-pure-css-4a29</link>
      <guid>https://forem.com/isarisariver/how-to-create-a-custom-tooltip-with-pure-css-4a29</guid>
      <description>&lt;p&gt;I always find the standard tooltip in browsers a bit boring, so I usually implement a custom one.&lt;/p&gt;

&lt;p&gt;The standard tooltip can be used by adding the title attribute to any Html element. When the user hovers over the element, the tooltip will show up after a short delay. Like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4 title="Looks boring and takes too long to show, right?!"&gt;Hover over me&lt;/h4&gt;




&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h2 title="DEV is a community of software developers"&amp;gt;
Dev.to
&amp;lt;/h2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;For the custom tooltip we need three items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The element that contains the tooltip&lt;/li&gt;
&lt;li&gt;A hovercard that contains the tooltip and is only visible when we hover over the element&lt;/li&gt;
&lt;li&gt;The tooltip content itself&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;In my example I have a list of links and when we hover over the link, we can see a short summary of the target of that link.&lt;/p&gt;

&lt;p&gt;Let's create the Html first.&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;li class="recent-link"&amp;gt;
  &amp;lt;a href="https://www.crumb-collector.com"&amp;gt;Crumb Collector&amp;lt;/a&amp;gt;
  &amp;lt;span class="hovercard"&amp;gt;
    &amp;lt;div class="tooltiptext"&amp;gt;
      Crumb Collector is a minimal and easy to use bookmark manager.
    &amp;lt;/div&amp;gt;
  &amp;lt;/span&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have a list-item element that contains a link, the hovercard and the tooltiptext.&lt;/p&gt;




&lt;p&gt;First we style the list-item. We have to assign the position property, so that we can position its children relative to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.recent-link {
  position: relative;
  color: #252525;
  padding-bottom: 18px;
  font-size: 1rem;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Next we position the hovercard. We make it invisible at first by setting &lt;code&gt;opacity: 0&lt;/code&gt;. The opacity changes to &lt;code&gt;opacity: 1&lt;/code&gt; when we hover over &lt;code&gt;.recent-link&lt;/code&gt;.&lt;br&gt;
By using &lt;code&gt;z-index: 1&lt;/code&gt; we make sure that is displayed on top of other content with a lower &lt;code&gt;z-index&lt;/code&gt; (by default 0).&lt;br&gt;
The positioning depends on the length and content of the tooltip. The longer the content, the more we have to offset the hovercard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.hovercard { 
  position: absolute; 
  opacity: 0; 
  z-index: 1;
  left: 50%;
  top: -90px;
  transform: translateX(-50%);
}

.recent-link:hover .hovercard { 
  opacity: 1; 
  transition: 0.5s;
  transition-delay: 0.1s;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Finally we style the tooltip itself, for example like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.tooltiptext {
  display: flex; 
  flex-direction: column; 
  justify-content: flex-start; 
  background-color: #0366d6;
  padding: 18px; 
  border-radius: 5px; 
  color: white; 
  line-height: 15px;
  transition: 1s;
  width: 200px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which looks like this:&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%2Fi%2Fsaga1p54pjqiyvpkbdtm.gif" 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%2Fi%2Fsaga1p54pjqiyvpkbdtm.gif" alt="Alt Text" width="496" height="234"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;We can do anything we want inside the tooltiptext-class. &lt;/p&gt;

&lt;p&gt;Let's say we want to display additional information about a user when we hover over the avatar (inspired by Squarespace).&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;div class="hovercard"&amp;gt;
        &amp;lt;div class="cover-image"&amp;gt;
          &amp;lt;div class="avatar"&amp;gt;A
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="username"&amp;gt;Plain Water&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="points"&amp;gt;2,345&amp;lt;/div&amp;gt;
        &amp;lt;ul class="stats"&amp;gt;
          &amp;lt;li class="stats-item"&amp;gt;Content Count: &amp;lt;/li&amp;gt;
          &amp;lt;li class="stats-item"&amp;gt;Joined: &amp;lt;/li&amp;gt;
          &amp;lt;li class="stats-item"&amp;gt;Last Visited: &amp;lt;/li&amp;gt; 
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fi%2Fo9jr8biyv4xi6pi6a6e2.gif" 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%2Fi%2Fo9jr8biyv4xi6pi6a6e2.gif" alt="Alt Text" width="612" height="702"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;Thanks for checking out this tutorial. Please let me know, if it is helpful and if you are interested in seeing more like this.&lt;br&gt;
If you have any questions, just let me know in the comments or shoot me a message. &lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
