<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Favourite Jome Blog]]></title><description><![CDATA[Sharing what I think I know about my Web Development Journey, learning new things and looking forward to learning more!]]></description><link>https://blog.favouritejome.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 11:13:57 GMT</lastBuildDate><atom:link href="https://blog.favouritejome.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My Year 2024 Milestones]]></title><description><![CDATA[As the year 2024 draws to a close, I find myself reflecting on how it all began with excitement, hope, and a dash of uncertainty. It’s incredible how much can change in just 12 months.
This article is a look back at a pivotal chapter of my life: how ...]]></description><link>https://blog.favouritejome.dev/my-year-2024-milestones</link><guid isPermaLink="true">https://blog.favouritejome.dev/my-year-2024-milestones</guid><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Mon, 16 Dec 2024 02:04:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734310995984/7c66aba6-2d8f-4490-845a-2239d3f02e45.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As the year 2024 draws to a close, I find myself reflecting on how it all began with excitement, hope, and a dash of uncertainty. It’s incredible how much can change in just 12 months.</p>
<p>This article is a look back at a pivotal chapter of my life: how I landed the opportunity to work at Hashnode as a Customer Success Engineer (CSE), the wins I celebrated, the challenges I faced, and the lessons I’m carrying forward into the new year.</p>
<p>Working at Hashnode has been nothing short of transformative, opening doors I never imagined and pushing me to grow in ways I didn’t expect. Join me as I share my journey, the highs and lows, and how this incredible experience has shaped my year.</p>
<h2 id="heading-getting-the-call-before-hashnode">Getting the Call - (Before Hashnode)</h2>
<p>On a faithful day, I was at a church program when I got the call from (<a class="user-mention" href="https://hashnode.com/@unclebigbay">Ayodele Samuel Adebayo</a> , aka Unclebigbay) asking if I would like to work at Hashnode as a Customer Success Engineer.</p>
<p>Although I did not know much about the role at the time, I quickly jumped at the opportunity once he explained some of the responsibilities. I said yes, and that was it.</p>
<p>On November 30th, 2023, I received a follow-up email from Samuel officially introducing me to <a target="_blank" href="https://hashnode.com/@sandeep">Sandeep</a> (<em>Officially because I had interacted with Sandeep casually before</em>). That’s how the journey began!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732716515708/1bd78091-e2ad-4713-9d7d-51605fccc200.png" alt class="image--center mx-auto" /></p>
<p>Sandeep and I arranged a meeting, during which I learned what was expected of me, what I needed to know, and that I would be on trial for a week to determine whether I would be a valuable member of the team.</p>
<p>During the interview, I remember Sandeep mentioning that one of the core values the team was looking for is someone with a CEO mindset, someone who is proactive, takes action without being prompted, and has a sense of urgency. So, have I been able to meet these expectations? Well, you'll have to read further to find out 😉</p>
<p>After the interview, I started working on Dec 1st, 2023, but on trial to see if I was fit for the role and the team; oh boy, did I put in my best efforts doing the trial. I was given access to Discord, and other tools needed to work.</p>
<p>Before the first week ended, I received a message from Sandeep saying my “work trial“ was a success, and that’s how I started 🙏.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732801232940/b4203a80-4ca9-4128-82e2-d7abdab43c80.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-early-days-at-hashnode">Early Days at Hashnode</h2>
<p>The early days at Hashnode were full of learning. I needed to understand our team's vision, the products (<a target="_blank" href="https://hashnode.com/products/docs">Docs by Hashnode</a> was being developed when I joined), and all the features. I also had to learn the best ways to communicate with our users about the various issues they encountered.</p>
<p>To give you an idea of what the role of a Customer Success Engineer (CSE) at Hashnode entails, here’s my scope of work:</p>
<ul>
<li><p><strong>Customer Interaction</strong>: Handle customer queries, provide technical assistance, and ensure customer satisfaction.</p>
</li>
<li><p><strong>Product Knowledge</strong>: Maintain in-depth knowledge of Hashnode's features, capabilities, and updates.</p>
</li>
<li><p><strong>Feedback Loop</strong>: Collect and relay customer feedback to the product and development teams for continuous improvement.</p>
</li>
<li><p><strong>Training and Education</strong>: Educate customers on product features, usage, and best practices.</p>
</li>
<li><p><strong>Problem Solving</strong>: Address and resolve technical issues faced by customers.</p>
</li>
<li><p><strong>Community Engagement</strong>: Actively participate in community discussions, providing insights and technical support.</p>
</li>
</ul>
<p>In short, my responsibilities as a CSE are to ensure our customers are satisfied with our products. This involves addressing customer queries, providing technical assistance, creating product documentation, and educating users. I also serve as a bridge between customers and the engineering team by relaying valuable feedback to help improve the product.</p>
<p>On the job, I got help from the team, helping the transition to the role, and looking back, I really disturbed my manager - Sandeep, with a lot of questions 😅</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732716475680/106e7f75-7e0c-4b30-9063-3d8cf4d054d9.png" alt class="image--center mx-auto" /></p>
<p>Over time, I became familiar with our customers' frequently asked questions, which helped me communicate and address their needs more effectively. For issues that required our engineers, I learned to ask the right questions to better convey them to the engineering team. I also became more mindful of how I respond to customers and handle the interesting issues they bring.</p>
<h2 id="heading-highlights-amp-events-amp-outside-work">Highlights &amp; Events &amp; Outside Work</h2>
<p>I promised myself that this year, I would make it a duty to try new things, go to more events than I had in previous years, network with like-minded people, and be exposed to other possibilities. I’d say I accomplished that.</p>
<h3 id="heading-sailconf-africa">Sailconf Africa</h3>
<p><a target="_blank" href="https://sailsconf.com/af">Sailconf Africa</a> was the first event I attended this year, on May 17th, 2024. It was organized by <a target="_blank" href="https://x.com/Dominus_Kelvin">Kelvin Omereshone</a>, <em>(the number 1 indie hacker I know)</em> and targeted at mid-level and senior web developers in Africa.</p>
<p>Though my role is in CSE, I saw it as a means to see some big guys we have in tech Nigeria and a means to travel to a new location for the first time - Abuja, the capital of Nigeria. Thanks once again to my boss for allowing me to go to this event, and of course, I talked about Hashnode while I was there 😉.</p>
<p>During the conference, I emerged as the winner of the squiddy game challenge, with the prize of 1 Million naira, by God’s grace. This was my first time winning that kind of money, so it was a big deal to me; you could see the excitement in my smile 😊.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733355606145/9534ff99-0185-424f-8dbb-b28304adf17c.gif" alt class="image--center mx-auto" /></p>
<p>I got to meet the one and only <a target="_blank" href="https://x.com/DaveyHert">David Herbert</a> for the first time, <a target="_blank" href="https://x.com/Dominus_Kelvin">Kelvin Omereshone</a>, <a target="_blank" href="https://x.com/babblebey">Olabode Lawal</a><strong>,</strong> <a target="_blank" href="https://x.com/toby_solutions">Tobiloba</a>, and other senior tech bro in the industry. It was really a memorable conference.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you’d like to watch the conference: - <a target="_self" href="https://www.youtube.com/live/FxB6ysnLteg?si=3UtJIlRrmjcZSSpu&amp;t=2171">Sailsconf Africa 2024 Day 1 Live</a>: timestamped where I was asked what I would do with the money if I won - (I said I’d give it to my mom and I did 😊). - <a target="_self" href="https://www.youtube.com/live/ZgEXFOqZktw?si=zOBPksSu9n8WhJPU&amp;t=32263">Sailsconf Africa 2024 Day 2 Live</a>: timestamped at the Squiddy Game challenge.</div>
</div>

<h3 id="heading-speaking-engagements">Speaking Engagements</h3>
<p>This year, I was privileged to have three speaking engagements, during which I shared the little I think I know with a global audience. The very first engagement was with the <a target="_blank" href="https://www.linkedin.com/company/faradayafrica/?originalSubdomain=ng">Faraday Africa</a> community, where I was invited to speak to new developers in their community on Web accessibility and SEO.</p>
<p><strong>Build 2.0: Web Accessibility and SEO</strong></p>
<blockquote>
<p>Feel free to watch the session below</p>
</blockquote>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=bPdqCoYLsMY">https://www.youtube.com/watch?v=bPdqCoYLsMY</a></div>
<p> </p>
<p>My next speaking engagement was at <a target="_blank" href="https://til-conf.netlify.app/">TIL Conf 2024</a>, where I discussed <strong>The Benefits of using Hashnode Headless CMS for Your Blog.</strong> It was a big conference with many great speakers, so I felt really nervous about giving my talk 😅.</p>
<p>Also, this was my first time giving a talk about Hashnode, and I knew there would be a lot of people watching. To make matters worse, my time allocated for the talk clashed with the day I went to <a target="_blank" href="https://sailsconf.com/af">Sailconf Africa</a>, so I had to reschedule the talk for the next day because my flight was delayed.</p>
<p>From the nervous feeling I had and not being able to get my laptop webcam working and then lending David Herbert a MacBook for the talk, I’d say I wasn’t as expressive with the talk as I previously planned. Well, I think it was okayish 😅</p>
<blockquote>
<p>You can find the <a target="_blank" href="https://www.youtube.com/watch?v=IneYPMWCLvU&amp;t=6946">session here</a>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733357577036/25027bc1-d57f-4de5-bc0b-f3607d8536c1.png" alt class="image--center mx-auto" /></p>
<p><strong>GraphQL 101: Learn to Build with GraphQL APIs</strong></p>
<p>My last speaking engagement was the Hashnode Webinar hosted by. I was brought on board to share the most basic approach to using GraphQL APIs based on the <a target="_blank" href="https://gql.hashnode.com/">Hashnode GraphQL API</a>.</p>
<p>I believe I did well in this talk, and I’m proud of the session. What do you think? Do watch it and let me know.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=2LyhUvdMCbI&amp;t=267s">https://www.youtube.com/watch?v=2LyhUvdMCbI&amp;t=267s</a></div>
<p> </p>
<h3 id="heading-the-day-i-turned-22">The day I turned 22</h3>
<p>Hashnode, Fazle, Sandeep, and the team made the day I turned 22 a very memorable day for myself and my family, and for that, I’m really grateful ❤️.</p>
<p>I was sent a huge cake, which made the day extra special. We just had to celebrate in our little way by getting drinks and taking pictures 😊</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733439849353/a0fa858a-5d86-49d2-9e02-b3c2b81b6c13.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733440077333/a342370f-f197-4dce-bd7f-a1762183b1a1.gif" alt class="image--center mx-auto" /></p>
<blockquote>
<p>My mom told me to change my outfit twice for pictures 😅</p>
</blockquote>
<h3 id="heading-books-read">Books Read</h3>
<p>Oh, I'm glad to say I read books this year. I joined a book club started by my friend <a target="_blank" href="https://www.linkedin.com/in/jesugbogo-enis/">Jesugbogo Enis</a>. It began as a "Read Two Books in April Challenge" but has now turned into a book club. My goal was to read 10 books before the year goes, but I ended up reading 6. Here are the books I’ve read with the help of the club.</p>
<p><a target="_blank" href="https://www.amazon.com/Psychology-Money-Timeless-lessons-happiness/dp/0857197681"><strong>The Psychology of Money</strong></a> by Morgan Housel</p>
<p>This was the first book we read, starting with the April challenge. In summary, I learned to think differently about money, how your environment can influence how you handle money, how saving and investing play a huge role in compounding wealth, the difference between getting wealthy and staying wealthy, and the importance of patience, humility, and long-term thinking.</p>
<blockquote>
<p>It was really a good book, I recommend.</p>
</blockquote>
<p><a target="_blank" href="https://www.amazon.com/Subtle-Art-Not-Giving-Counterintuitive/dp/0062457713"><strong>The Subtle Art of Not Giving a F*ck</strong></a> by Mark Mansion</p>
<p>This book highlights how much better we’d feel, improve, and succeed in areas of our life if we don’t pay attention to things we shouldn’t pay attention to, things that aren’t important. There were other insightful and interesting points highlighted by Mark, and I’d say it was a good read.</p>
<blockquote>
<p>If you’re not comfortable with the F word, then I wouldn’t recommend, cause it was used a lot 😑</p>
</blockquote>
<p><a target="_blank" href="https://tkoinsights.com/product/unleash/"><strong>Unleash: The Blueprint for a Life that Attracts Uncommon Opportunities</strong></a> by Topsy Kola-Oyeneyin</p>
<p>The book Unleash was centered around youths (young ones) like myself, saying we aren’t too young to unleash our potential inert in us. There were a total of 12 dimensions mentioned in the book, around “How we are to operate”, “how to relate,” and “how to work, “ laying the blueprints we are following, unleashing uncommon opportunities.</p>
<blockquote>
<p>This is my favourite book of the year, highly recommend for everyone, young and old.</p>
</blockquote>
<p><a target="_blank" href="https://jamesclear.com/atomic-habits"><strong>Atomic Habits: An Easy &amp; Proven Way to Build Good Habits &amp; Break Bad Ones</strong></a> by James Clear</p>
<p>Atomic Habits, a book I’ve had since last year but never read completely until the book challenge in July, 2024 😅. The book focuses on laws, principles, and guidelines one can take to either break old habits or form a new habit. How tiny changes daily or frequently can compound to an unimaginable difference.</p>
<blockquote>
<p>I do feel I need to re-read this book to digest the principles in the book, it’s really a good book for everyone to read, highly recommend.</p>
</blockquote>
<p><a target="_blank" href="https://www.amazon.com/Finish-What-You-Start-Self-Discipline/dp/1986622312"><strong>Finish What You Start</strong></a> by Peter Hollins</p>
<p>Favourite, finish what you start….👀</p>
<p>That’s what I got out of the book. It spoke to me, saying I should finish what I had started and describing different techniques I can apply, like temptation bundling — a process of combining an undesirable task with a required task for instantaneous reward.</p>
<blockquote>
<p>Honestly, I still struggle finishing what I start, for example the article took forever to be completed - if I wrote everyday I should have been done with it, but then…</p>
<p>If you see this article, and get to this point of the article, make sure to comment, congrats on finishing the article 😂</p>
<p>Well this is a good book to read, similar in some ways like Atomic Habits</p>
</blockquote>
<p><a target="_blank" href="https://www.amazon.com/How-Win-Friends-Influence-People/dp/0671027034"><strong>How to Win Friends and Influence People</strong></a> by Dale Carnegie</p>
<p>Oh, what a great book this was. The book went on into the psychology of human interactions, where Part 1 mentioned the “Fundamental techniques in handling people”, Part 2: “Six ways to make people like you”, Part 3: “How to win people to your way of thinking” and Part 4: “Be a leader: How to change people without giving offense or arousing resentment.” Some of the principles from the book I keyed into are: Part 1 - Principle 2: <strong>Give honest and sincere appreciation</strong>; Part 3 - Principle 6: <strong>Let the other person do a great deal of the talking,</strong> Part 4 <strong>-</strong> Principle 7: <strong>Give the other person a fine reputation to live up to,</strong> e.t.c</p>
<blockquote>
<p>The book is fill with gems for winning friends and dealing with people generally, a great book I must add and I highly recommend.</p>
</blockquote>
<p>In the spirit of reading, I bought myself a new collection of books, and I’m looking forward to reading them next year.</p>
<blockquote>
<p>If you have books you recommend, do let me know 😉</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734043538456/941a0565-63c6-4361-8d54-25a101f015e7.jpeg" alt class="image--center mx-auto" /></p>
<blockquote>
<p>The books to the left and the new one’s I got.</p>
</blockquote>
<h3 id="heading-other-events-and-highlights">Other Events and Highlights</h3>
<p>Here are some of the other events I was privileged to attend over the course of the year:</p>
<ul>
<li><p><a target="_blank" href="https://www.instagram.com/roundtable_community/?hl=en">The Roundtable 3.0 - A Village Assembly for Young People Seeking More</a> convener <a target="_blank" href="https://www.youtube.com/@kennedy.ekezie">Kenny Ekezie</a> 🤩</p>
</li>
<li><p><a target="_blank" href="https://devfestlagos.com/">DevFestLagos</a> 👍</p>
</li>
<li><p><a target="_blank" href="https://www.africastartupfestival.com/en">Africa Startup Festival</a> 🤩</p>
</li>
<li><p><a target="_blank" href="https://www.instagram.com/impossiblesummit_/">Impossible Submit</a> 🤩🙏</p>
</li>
<li><p>Weddings 😍</p>
</li>
<li><p>Entrepreneurship Program with Olubori Paul 🤩</p>
</li>
<li><p>Visited Samuel's home and worked with him 🤩</p>
</li>
</ul>
<h3 id="heading-dev-work-done-at-hashnode">Dev work done at Hashnode</h3>
<p>At some point, I missed coding, and I was looking for an opportunity to work on the codebase at Hashnode. Thankfully, Sandeep gave me an opportunity, and my first coding task was to develop the <a target="_blank" href="https://hashnode.com/hackathons/ai-for-tomorrow?source=ai">AI for Tomorrow</a> hackathon page.</p>
<p>The hackathon page was fun to build, and there were a lot of “<strong>what I designed isn’t correctly implemented</strong>“ from <a class="user-mention" href="https://hashnode.com/@UXpaul">Pritam Paul</a> 😅</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734043682042/59db020b-cf82-441d-ae9b-49e02c5bbe39.png" alt class="image--center mx-auto" /></p>
<p>My major task was migrating the <a target="_blank" href="https://hashnode.com/settings">account settings page</a> to the new layout you see today. Well working on this, I really went through the amazing code written by the other engineers, learning from the works and implementing. <a class="user-mention" href="https://hashnode.com/@unclebigbay">Ayodele Samuel Adebayo</a> was my code reviewer along this journey, and it was great working with him 🤩</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734041526665/49070378-878a-4ed8-9fa2-2759cfb5c81f.png" alt class="image--center mx-auto" /></p>
<p>A work I’m proud of is building an app that allows users to migrate their blog from Ghost to Hashnode. At some point, I was getting a lot of requests regarding this same request, and unfortunately, we don’t support migrating from Ghost to Hashnode yet. While looking into the issue, I ended up building a solution, and I’m glad I got good feedback for the effort 😊.</p>
<blockquote>
<p>Here’s the <a target="_blank" href="https://ghost-hashnode-migration.vercel.app/">app</a>, if you’d like to try it out.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734042063274/aedfa227-4391-4a72-8610-f314c9d7e62a.png" alt class="image--center mx-auto" /></p>
<p>A minor development work I worked on is the personalized feed widget you see on the community feed. Allowing users to personalize their feeds by following different tags.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734042383392/2c5cd812-0dae-44c9-a76c-2fd0e0fdb3c3.gif" alt class="image--center mx-auto" /></p>
<h2 id="heading-trip-to-india-hashnode-workcation">Trip to India - Hashnode Workcation</h2>
<p>The trip to India was my first international journey, and I must say, it was an incredible experience going abroad for the first time. Traveling on three planes from Nigeria to Bengaluru, India, was surreal; after thinking how it was going to be for too long, I’m glad everything worked out. Also, shout out to <a target="_blank" href="https://www.instagram.com/kaijego/#">Kaijego</a> for helping me with the Visa process and for tips I needed to know before traveling.</p>
<p>The Hashnode Workcation at Bengaluru (or Bangalore) was for a week, planned to bring the entire team together, to work together as a team in a physical location and to discuss our future plans for the company growth and, most importantly unwind which we did all.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731778920987/f4833e44-e18b-41dd-a149-149463e2d93c.jpeg?auto=compress,format&amp;format=webp" alt /></p>
<p>I got to try out different Indian foods, like dosa and tea. Some foods were <strong>PRETTY GOOD,</strong> and others spicy, but I ended up liking <a target="_blank" href="https://en.wikipedia.org/wiki/Dosa_\(food\)#:~:text=A%20dosa%2C%20dose%2C%20dosai%2C,lentil%2Dbased%20vegetable%20stew\).">Dosa</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734303497945/3d72e5bd-030f-44df-bf8c-ccfc24677fef.gif" alt class="image--center mx-auto" /></p>
<p>While working, <a class="user-mention" href="https://hashnode.com/@Haimantika">Haimantika Mitra</a> and I, worked towards launching <a target="_blank" href="https://docs.hashnode.com/">docs.hashnode.com</a> - Hashnode new documentation. It was launched the following week after the workcation.</p>
<blockquote>
<p>Do check the docs and let us know your feedback, it was great working on it and I’d love feedbacks from you all - <a target="_blank" href="https://docs.hashnode.com/">docs.hashnode.com</a></p>
</blockquote>
<p>We celebrated <a class="user-mention" href="https://hashnode.com/@lakbychance">Lakshya Thakur</a> for his 3rd year anniversary at Hashnode and also <a class="user-mention" href="https://hashnode.com/@JannikWempe">Jannik Wempe</a>’s birthday 🥳</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734306049122/56cf508a-3186-4e5d-9b17-16c669092859.png" alt class="image--center mx-auto" /></p>
<p>On our last day in Bangalore, I knew I had a lot of fun 😅. We explored a park, went jogging, had our last dinner together as a team, and played different games—go-karting, Laser tag, and Bowling.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734307562858/6a8ce6e0-3c30-435a-bea7-683707464a71.gif" alt class="image--center mx-auto" /></p>
<p>Overall, the trip to India was a beautiful experience. I got to interact with everyone on the team present, and we had personal discussions—not just work-related ones. I also got to know everyone a little better.</p>
<h2 id="heading-reflection">Reflection</h2>
<p>From joining Hashnode in 2020, trying new things, like technical writing and building connections, to now working for a global company. It’s been a journey, and I’m grateful to God for the privilege and opportunities.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734302593323/632da6bc-a066-4a0c-9fc0-62dcb1f9f598.png" alt class="image--center mx-auto" /></p>
<p>Also, to the Hashnode team, my managers, Sandeep and Fazle, and my colleagues thank you for making the year extra special. I’m grateful. Especially to Samuel, thank you for the call and recommendation, I’m grateful 🙏</p>
<p>On December 1st, I also celebrated my 1st anniversary at Hashnode 🤩</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734306592885/22c00034-9d77-4b58-bbf0-64986c382b4e.png" alt class="image--center mx-auto" /></p>
<p>As much as I feel I unlocked some boxes this year, I know there are areas where I felt too relaxed and need to step up in the coming year. These include</p>
<ul>
<li><p>writing about what I’m learning and sharing it here,</p>
</li>
<li><p>reading and actually executing the knowledge I've gained,</p>
</li>
<li><p>building more connections with people,</p>
</li>
<li><p>advocating Hashnode and our products better and louder,</p>
</li>
<li><p>broaden my horizons by exploring new things - stepping outside my comforts</p>
</li>
<li><p>getting back to creating videos on my <a target="_blank" href="https://www.youtube.com/@favouritejome">YouTube channel</a>,</p>
</li>
<li><p>learning more technical things so I don’t get lost and</p>
</li>
<li><p>working towards growing my faith</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>2024 was a year beyond my expectations. I achieved some personal milestones I didn’t think were possible in a few years to come, as well as in my growth and life. I can’t wait to see what 2025 brings.</p>
<p>Thank you for reading and being part of my 2024 journey, and I wish you a Merry Christmas and a Happy New Year in advance 🎊.</p>
<p>Cheers to 2025 🥳</p>
]]></content:encoded></item><item><title><![CDATA[CSS Text Outline: How to Make Creative Typography Stroke]]></title><description><![CDATA[💡
Originally posted here.


In the intricate world of web design today, typography serves as a powerful means of expression, improving site usability and it goes beyond the realms of font choice and sizes. In this article we’ll explore a sub-section...]]></description><link>https://blog.favouritejome.dev/css-text-outline-how-to-make-creative-typography-stroke</link><guid isPermaLink="true">https://blog.favouritejome.dev/css-text-outline-how-to-make-creative-typography-stroke</guid><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Fri, 08 Nov 2024 12:24:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731068472947/416c9e72-c0d8-4ec3-a762-56ebab864bea.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_self" href="https://purecode.ai/blogs/css-outline-text">Originally posted here</a>.</div>
</div>

<p>In the intricate world of web design today, typography serves as a powerful means of expression, improving site usability and it goes beyond the realms of font choice and sizes. In this article we’ll explore a sub-section of Web Typography, that is, dealing with CSS text outline, also known as typography stroke, along with the various methods we can follow to achieve stroke effect in CSS.</p>
<p>Web typography, often referred to as web text, constitutes a form of vector-based graphics within the digital landscape. This characteristic enables web typography to scale seamlessly, mirroring the behaviour of standard Scalable Vector Graphics (SVGs). The scalability of web typography is a key feature that ensures optimal visual experiences across a diverse range of devices and screen sizes.</p>
<p>In essence, the vector-based nature of web typography means that the characters are defined by mathematical equations rather than fixed pixels. This inherent flexibility allows text elements to adapt gracefully, maintaining clarity and legibility whether viewed on a small smartphone screen or a large desktop monitor.</p>
<p>Since we’ve established that Web typography is essentially vector-based graphics, then Web typography should also be able to do things just like design software that deals with vector-based graphics would, e.g. Adobe Illustrator.</p>
<h2 id="heading-what-is-text-outline-or-typography-stroke"><strong>What is Text Outline or Typography Stroke?</strong></h2>
<p>In the context of design, a “<strong>stroke</strong>” typically refers to the outline of a shape or text element. It is a visual attribute that adds a defined boundary to a shape or text, helping it stand out and providing emphasis. Meanwhile, a “<strong>fill</strong>“ refers to the interior area of a shape or object that is enclosed by its outline or border. It is the part of the element that is solid or filled with colour, pattern, or texture.</p>
<p>In the realm of typography, a “text stroke” or “typography stroke” or “text outline” specifically refers to the outlined border around the characters of a text.</p>
<p>Here’s an image that illustrate where the stroke and fill are located:</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/320ddb9b-005d-4bc3-9dc0-8c56dbe434c5.png" alt /></p>
<p>With CSS (Cascading Style Sheets), <strong>strokes</strong> can be applied to text using properties such as <strong>text-stroke</strong>, enhancing the visual appeal of typography on the web. These strokes can be customised to achieve different effects, contributing to the overall aesthetic and readability of the text. Whether it’s a subtle accent or a bold statement, understanding and utilising strokes play a crucial role in graphic design and digital communication.</p>
<h2 id="heading-stroked-typography-in-css"><strong>Stroked Typography in CSS</strong></h2>
<p>In CSS, stroked typography can be created in three methods:</p>
<ul>
<li><p>Using the non-standard <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-text-stroke">webkit-text-stroke</a> property</p>
</li>
<li><p>Using text-shadow property</p>
</li>
<li><p>Using pseudo-element hack</p>
</li>
</ul>
<h3 id="heading-using-the-non-standard-webkit-text-stroke-property"><strong>Using the non-standard webkit-text-stroke property</strong></h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-text-stroke"><strong>webkit-text-stroke</strong></a> property is a non-standard CSS property that is used to apply <strong>width</strong> and <strong>color</strong> of strokes or outlines to text characters. It’s a shorthand property for the longhand properties <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-text-stroke-width">-webkit-text-stroke-width</a> and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-text-stroke-color">-webkit-text-stroke-color</a>.</p>
<p>The example below is equivalent:</p>
<pre><code class="lang-markdown">-webkit-text-stroke: 4px navy;

OR

-webkit-text-stroke-width: 4px;
-webkit-text-stroke-color: navy;
</code></pre>
<p>Here’s an example of how you can use <strong>-webkit-text-stroke</strong> property:</p>
<pre><code class="lang-markdown">/<span class="hljs-emphasis">* CSS file *</span>/

h1 {
  /<span class="hljs-emphasis">* Apply a black stroke with a width of 2 pixels *</span>/
  -webkit-text-stroke: 2px black;

  /<span class="hljs-emphasis">* Set the text fill color to white *</span>/
  color: white;

  /<span class="hljs-emphasis">* Optional: Adjust other styling properties *</span>/
  font-size: 180px;
  font-family: 'Arial', sans-serif;
  text-align: center;
}
</code></pre>
<pre><code class="lang-markdown"><span class="xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span>Hello World<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre>
<h3 id="heading-preview"><strong>Preview</strong></h3>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/d092d84b-9067-4e10-9112-07779d72423f.png" alt="Hello World text with stroke applied" /></p>
<p>In this example, the <strong>-webkit-text-stroke</strong> property is applied to an h1 element, creating a black stroke around the text. The color property is set to white to ensure that the text inside the stroke is filled with a contrasting color.</p>
<p>From the example above, everything seems to work fine, but let’s say we increase the <strong>-webkit-text-stroke-width</strong> property value to 20px and change the color to red to see the effect properly.</p>
<pre><code class="lang-markdown">/<span class="hljs-emphasis">* CSS file *</span>/

h1 {
  -webkit-text-stroke-width: 20px;
  -webkit-text-stroke-color: black;

  color: red;

  font-size: 180px;
  font-family: 'Arial', sans-serif;
  text-align: center;
}
</code></pre>
<h3 id="heading-preview-1"><strong>Preview</strong></h3>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/7863203b-5558-4787-a9cd-2bbfcea6767d.png" alt="-webkit-text-stroke-width increased" /></p>
<p>Wow, now the text starts looking really ugly and misshapen. This is because the stroke is positioned above the fill and resides within the confines of the text. In simpler terms, the stroke is above the fill or color of the text, placed in the center of the text. So how do we fix this?</p>
<p>The sad reality is that there’s no proper fix for this issue yet, as of 2023, and even design software like Adobe Illustrator has this same problem, where with texts, you can’t change the alignment of the stroke from being centered.</p>
<p>Here’s a GIF to illustrate the same issue with Adobe Illustrator 2022.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/9dead888-4179-4cb7-ac70-db6434ccb332.png" alt /></p>
<p>However, there’s a property that kinda fixes this issue, but as of 2023, it only works on Firefox browser. The CSS property is called <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/paint-order">paint-order</a>, which helps to control the order in which the fill and stroke text content are drawn. With the <strong>paint-order</strong> CSS property, the stroke will be placed outside the text color or fill.</p>
<h3 id="heading-heres-how-it-looks-on-firefox-browser-windows"><strong>Here’s how it looks on Firefox browser (Windows)</strong></h3>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/33c825dd-4dff-4a0f-8f30-cd907a0736e2.png" alt /></p>
<p>Here’s what changed in the CSS file, and all we introduced was <strong>paint-order: stroke</strong> which does the magic.</p>
<pre><code class="lang-markdown">/<span class="hljs-emphasis">* CSS file *</span>/

h1 {
  -webkit-text-stroke: 20px black;
  color: red;

  /<span class="hljs-emphasis">* Set Paint-Order property *</span>/
  paint-order: stroke;

  font-size: 180px;
  font-family: 'Aria', sans-serif;
  text-align: center;
}
</code></pre>
<blockquote>
<p>Notice on Firefox browser, the stroke corners are curved by default.</p>
</blockquote>
<p>On Google Chrome browser, the result remains the same, the <strong>paint-order</strong> property has no effect at all, sadly 😑.</p>
<blockquote>
<p>Here’s the <a target="_blank" href="https://codepen.io/jome-favourite/pen/MWLPYGo">CodePen link</a> if you’d like to preview it for yourself.</p>
</blockquote>
<p>The <strong>-webkit-text-stoke, -webkit-text-stroke-width,</strong> and <strong>-webkit-text-stroke-color</strong> CSS properties all have good support in major browsers, and according to <a target="_blank" href="https://caniuse.com/">caniuse.com</a> it has <a target="_blank" href="https://caniuse.com/?search=-webkit-text-stroke">96.89% support across all major browsers</a> as of November 2023.</p>
<h4 id="heading-pros"><strong>Pros</strong></h4>
<ol>
<li><p>Easy to use, as it requires a single property</p>
</li>
<li><p><a target="_blank" href="https://caniuse.com/?search=-webkit-text-stroke">Very well supported in modern browsers</a></p>
</li>
</ol>
<h4 id="heading-cons"><strong>Cons</strong></h4>
<ol>
<li><p>Achieving a satisfactory result can be challenging when combining a colour and a stroke.Though the <strong>paint-order</strong> property helps, but it’s only supported in one browser.</p>
</li>
<li><p>Being a non-standard property, there’s a possibility that it might be removed and substituted in future updates. Additionally, there could be variations or inconsistencies across different browsers.</p>
</li>
</ol>
<h3 id="heading-using-text-shadow-property"><strong>Using text-shadow property</strong></h3>
<p>The <strong>text-shadow</strong> method is more of a hacky solution, where multiple shadows with different offsets can be used to simulate the text stoke. With the approach, we are guaranteed that the simulated stroke with shadows would also be beneath the text content at every point.</p>
<p>If you think about it, we’ll need the shadows to cover every direction of each character in the text, i.e. top, right, bottom, and left. Let’s see an example:</p>
<pre><code class="lang-markdown">/<span class="hljs-emphasis">* CSS File *</span>/

h1 {
  /<span class="hljs-emphasis">* Simulate text-stroke with multiple shadows *</span>/
  text-shadow: 
<span class="hljs-code">     1px 1px 0px #000,   /* Bottom right */
     -1px -1px 0px #000,  /* Top left */
     1px -1px 0px #000,  /* Top right */
     -1px 1px 0px #000;   /* Bottom left */     
</span>
  /<span class="hljs-emphasis">* Optional: Additional styling *</span>/
  color: #fff;  /<span class="hljs-emphasis">* Text color *</span>/
  font-size: 180px;
  font-family: 'Arial', sans-serif;
  text-align: center;
}
</code></pre>
<p><strong>Preview</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/42d566cf-b807-47ea-a33f-8fd5c8b7f91f.png" alt="Hello World with text shadow hack" /></p>
<blockquote>
<p>See the preview on <a target="_blank" href="https://codepen.io/jome-favourite/pen/eYxPNzj">CodePen</a></p>
</blockquote>
<p>In this example, the text-shadow property is used to create a simulated text-stroke effect by applying shadows in each direction. Additionally, the shadows have a 0px blur radius (0px), ensuring a crisp outline.</p>
<p>Also, looking at the preview, it looks pretty close to what we had first with the <strong>-webkit-text-stroke</strong> property, but there’s a challenge, how do we tell what the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow">offset X and Y length</a> values should be? Let’s say we increased the offset X and Y length values to 3px. So, let’s see what happens:</p>
<pre><code class="lang-markdown">/<span class="hljs-emphasis">* CSS File *</span>/

h1 {
  /<span class="hljs-emphasis">* Simulate text-stroke with multiple shadows *</span>/
  text-shadow: 
<span class="hljs-code">     3px 3px 0px #000,    /* Bottom right */
     -3px -3px 0px #000,  /* Top left */
     3px -3px 0px #000,   /* Top right */
     -3px 3px 0px #000;   /* Bottom left */     
</span>
  /<span class="hljs-emphasis">* Optional: Additional styling *</span>/
  color: #fff;  /<span class="hljs-emphasis">* Text color *</span>/
  font-size: 180px;
  font-family: 'Arial', sans-serif;
  text-align: center;
}
</code></pre>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/83fd493e-f6fb-427e-be88-7c7639dec9e0.png" alt="text shadow - text stroke effect with 3px offset x and y length values" /></p>
<blockquote>
<p>Here’s the <a target="_blank" href="https://codepen.io/jome-favourite/pen/ExrdjmM">CodePen link</a> to preview</p>
</blockquote>
<p>With keen eyes, you’d notice that there are gaps in some characters of the text, like the <strong>“e”</strong> and <strong>“r”</strong>. To help show the gap, here is the same image but zoomed in.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/b3568f73-e741-4d2b-a40d-68c7da6186c0.png" alt /></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/db1661ff-1ff2-456a-9452-08ed3cfa7ccf.png" alt /></p>
<p>To fix the gaps, we’ll need to add more shadows, but then this method isn’t sufficient cause you’d likely be guessing the shadow offset would be tedious, except you’re a maths wizard 😅. Here’s an article that shows how using <a target="_blank" href="https://unused-css.com/blog/css-text-strokeoutline/#using-8-box-shadows">8 multiple shadows solved</a> the gap problem.</p>
<h4 id="heading-pros-1"><strong>Pros</strong></h4>
<ol>
<li><p>It works properly when the offset X and Y length values are just 1px.</p>
</li>
<li><p>It is widely supported across all major browsers</p>
</li>
</ol>
<h4 id="heading-cons-1"><strong>Cons</strong></h4>
<ol>
<li><p>Introduces gaps in the simulated stroke effect if the shadow X and Y offset is greater than 1px</p>
</li>
<li><p>It’s too hacky cause you’d have to guess the shadow offsets.</p>
</li>
<li><p>Strokes aren’t shape as it should, they may appear blurry.</p>
</li>
</ol>
<h3 id="heading-using-pseudo-element-hack"><strong>Using pseudo-element hack</strong></h3>
<p>With the help of pseudo-elements, we can simulate the text stroke effect by creating a copy of the text content and then apply the <strong>-webket-text-stroke</strong> property to the pseudo-element. With the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/attr"><strong>attr()</strong></a> CSS function and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes"><strong>data-* attribute</strong></a>, we can achieve the text stroke effect.</p>
<p>Enough explanation; let’s see an example to understand how to utilise the pseudo-element hack.</p>
<pre><code class="lang-markdown"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">data-text</span>=<span class="hljs-string">"Hello World"</span>&gt;</span></span>Hello World<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre>
<p>The <strong>data-*</strong> attribute is used on the HTML element in order for the attribute value “Hello World” to be gotten from CSS with the help of the <strong>attr()</strong>. Here’s how we get the <strong>data-text</strong> attribute value in CSS.</p>
<pre><code class="lang-markdown">h1 {
   color: red;
   font-size: 180px;
   font-family: 'Aria', sans-serif;
   position: relative;
}

h1::after {
   /<span class="hljs-emphasis">* data-text atrribute value gotten as the content value in CSS *</span>/
   content: attr(data-text);

   position: absolute;
   top: 0;
   left: 0;

   /<span class="hljs-emphasis">* Place the pseudo-element below the actual text *</span>/
   z-index: -1;
   /<span class="hljs-emphasis">* Relative to h1 *</span>/
   font-size: 1em;

   -webkit-text-stroke: 20px black;
}
</code></pre>
<p><strong>Preview</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/b137f23f-116a-454e-b1e6-b1f10fa1f44f.png" alt="Hello World text stroke effect with Pseudo element " /></p>
<blockquote>
<p>Here’s the <a target="_blank" href="https://codepen.io/jome-favourite/pen/mdvzWyQ">CodePen link</a></p>
</blockquote>
<p>In the example above, we had a lot of properties flying around, like the position <strong>relative</strong> and <strong>absolute</strong> values. On the <strong>h1</strong> CSS type selector, notice the <strong>position: relative</strong> CSS declarion, it’s very important, cause the <strong>h1</strong> pseudo element selector would be positioned absolute to the h1 element. Also, the <strong>top</strong>, and <strong>left</strong> property has the value 0.</p>
<p>The issue with the pseudo-element hack, is that if the h1 selector changes its position, let’s say the text is aligned to the center, the text stroke effect breaks. Here’s an example to see how it breaks:</p>
<pre><code class="lang-markdown">h1 {
   color: red;
   font-size: 180px;
   font-family: 'Aria', sans-serif;
   position: relative;

   /<span class="hljs-emphasis">* New CSS declaration added *</span>/
   text-align: center;
}

h1::after {
   /<span class="hljs-emphasis">* data-text atrribute value gotten as the content value in CSS *</span>/
   content: attr(data-text);

   position: absolute;
   top: 0;
   left: 0;

   /<span class="hljs-emphasis">* Place the pseudo-element below the actual text *</span>/
   z-index: -1;
   /<span class="hljs-emphasis">* Relative to h1 *</span>/
   font-size: 1em;

   -webkit-text-stroke: 20px black;
}
</code></pre>
<p><strong>Preview</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/3cd368e6-9f43-4783-a603-e7570a8614b2.png" alt /></p>
<h4 id="heading-pros-2"><strong>Pros:</strong></h4>
<ul>
<li><p>Effectively generates a stroke around the text.</p>
</li>
<li><p>The stroke adjusts proportionally when the font-size of the element (e.g., an h1 tag) changes.</p>
</li>
</ul>
<h4 id="heading-cons-2"><strong>Cons:</strong></h4>
<ul>
<li><p>Requires duplicating text content in a custom attribute.</p>
</li>
<li><p>Shares similar drawbacks with <strong>-webkit-text-stroke-width</strong> when used for stroke creation, potentially requiring mathematical adjustments to avoid using this property.</p>
</li>
<li><p>Issues may arise when the element alignment is changed.</p>
</li>
</ul>
<h2 id="heading-combining-text-stroke-and-text-shadow-properties"><strong>Combining text-stroke and text-shadow Properties</strong></h2>
<p>Combining the <strong>text-stroke</strong> and <strong>text-shadow</strong> properties in CSS opens up a realm of possibilities for creating visually compelling and dynamic text effects. These properties, when used in conjunction, allow for intricate and layered styling, enhancing the overall aesthetic impact of your typography.</p>
<p>Here are some examples showcasing how you can combine <strong>text-stroke</strong> and <strong>text-shadow</strong>.</p>
<h3 id="heading-example-1"><strong>Example 1</strong></h3>
<pre><code class="lang-markdown">h4 {
  /<span class="hljs-emphasis">* Apply a text-stroke with a white color and a width of 2 pixels *</span>/
  -webkit-text-stroke: 2px white;
  color: black; /<span class="hljs-emphasis">* Set the text color *</span>/

  /<span class="hljs-emphasis">* Add a subtle text-shadow for depth and dimension *</span>/
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);

  /<span class="hljs-emphasis">* Optional: Additional styling *</span>/
  font-size: 180px;
  font-family: 'Arial', sans-serif;
  text-align: center;
}
</code></pre>
<p>In this example, the <strong>-webkit-text-stroke</strong> property is used for the <strong>text-stroke</strong> effect, creating a white outline around the text characters. The text-shadow property is then applied to add a subtle shadow, providing depth and dimension to the text.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/dc1e7c2d-009b-4002-a567-33f08f4eb750.png" alt="text shadow and text stroke effect - example one" /></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/PoVypgq">https://codepen.io/jome-favourite/pen/PoVypgq</a></div>
<p> </p>
<h3 id="heading-example-2"><strong>Example 2</strong></h3>
<p>To peek at the code used to achieve this example, here’s the <a target="_blank" href="https://codepen.io/jome-favourite/pen/poGxPgd">CodePen</a> link:</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/bca4f0f0-43d5-4c12-be29-5294493f0081.png" alt="text shadow and text stroke effect - example two" /></p>
<h3 id="heading-example-3"><strong>Example 3</strong></h3>
<p>Here’s the <a target="_blank" href="https://codepen.io/jome-favourite/pen/MWLPmeV">CodePen link</a>, for the Neon effect:</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/bb250c0a-c988-421f-bdf7-c2fe88aaa617.png" alt="text shadow and text stroke effect - example three" /></p>
<h2 id="heading-creative-typography-stroke-examples"><strong>Creative Typography Stroke Examples</strong></h2>
<p>Let’s look at more examples that are creative:</p>
<h3 id="heading-example-1-1"><strong>Example 1</strong></h3>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/f00503c4-1a48-4963-90b8-bf2118246900.png" alt="Stroke effect - Example 1" /></p>
<pre><code class="lang-markdown"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span>Stroke<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre>
<pre><code class="lang-markdown">body {
  background: black;
}

h1 {
  background-image: linear-gradient(90deg, #ff00d2, #fed90f, #00a2ff);
  background-clip: text;
  -webkit-text-stroke-color: transparent;
  -webkit-text-stroke-width: calc(1em / 16) ;
  -webkit-background-clip: text;
  color: #000119;
  font-size: 22vmin;
  font-weight: 700;
  text-align: center;
}
</code></pre>
<blockquote>
<p><em>This stroke effect is referenced from the</em> <a target="_blank" href="https://www.youtube.com/watch?v=icnixsbLpQg"><em>video by SoftCode</em></a></p>
<p><a target="_blank" href="https://codepen.io/jome-favourite/pen/jOdemZz">Codepen link to view the preview.</a></p>
</blockquote>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/jOdemZz">https://codepen.io/jome-favourite/pen/jOdemZz</a></div>
<p> </p>
<h3 id="heading-example-2-1"><strong>Example 2</strong></h3>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/ec20a3ce-119f-4fb4-b3b9-39ecf9ef67eb.png" alt="Lemon text stoke effect" /></p>
<pre><code class="lang-markdown"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span>Lemon<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre>
<pre><code class="lang-markdown">@import url('https://fonts.cdnfonts.com/css/spicy-rice');

body {
  background-image: url(https://st3.depositphotos.com/5489530/13659/i/600/depositphotos<span class="hljs-emphasis">_136593476-stock-photo-lime-and-mint-detox-water.jpg);
  background-color: #5DB318;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: bottom bottom;
}

h1 {  
color: rgba(154, 41, 162, 0);
    font-family: "Spicy Rice", Sans-serif;
    font-size: 165px;
    font-weight: normal;
    text-shadow: -6px 10px 0px #5DB318;
    mix-blend-mode: darken;
    -webkit-text-stroke: 2px #FFFFFF;
    text-stroke: 2px #FFFFFF;
    text-align: right;
}</span>
</code></pre>
<blockquote>
<p><em>The stroke effect was reference in</em> <a target="_blank" href="https://happyaddons.com/text-stroke/"><em>happyaddons website</em></a></p>
<p><a target="_blank" href="https://codepen.io/jome-favourite/pen/eYxPWXX">Codepen link to view the preview</a></p>
</blockquote>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/eYxPWXX">https://codepen.io/jome-favourite/pen/eYxPWXX</a></div>
<p> </p>
<h2 id="heading-browser-support-for-text-stroke-property"><strong>Browser Support For text-stroke Property</strong></h2>
<p>According to <a target="_blank" href="https://caniuse.com/?search=text%20stroke">caniuse.com</a>, 96.89% of all browsers support the <strong>-webkit-text-stroke</strong> property except for all versions of Internet Explorer browser and Opera mini browser. However, the other browsers support the text-stroke property by making use of the webkit prefix to ensure compatibility.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2023/12/7e4bac6e-3973-4662-8b4b-09e29300c68a.png" alt="Caniuse.com" /></p>
<h2 id="heading-wrapping-up"><strong>Wrapping Up</strong></h2>
<p>In wrapping up our look at text-stroke in CSS, we’ve covered a few cool ways to make your text stand out. Whether you’re using the <strong>-webkit-text-stroke</strong> property for a basic outline, getting creative with <strong>pseudo-elements</strong>, or adding depth with <strong>text-shadow</strong>, these methods give you options to make your typography pop. In addition, each approach has its strengths, offering flexibility for different design needs. So, play around, try them out, and let your text be a canvas for your creativity!</p>
<p>Here are also some helpful resources about the text-stroke:</p>
<ul>
<li><p><a target="_blank" href="https://css-tricks.com/adding-stroke-to-web-text/">Adding Stroke to Web Text</a></p>
</li>
<li><p><a target="_blank" href="https://unused-css.com/blog/css-text-strokeoutline/">CSS Text Stroke/Outline</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=I4IENYMnyTw">3 Simple Techniques to Create a Text Stroke in HTML and CSS</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Easy CSS Techniques to Center Images for Enhanced Web Layouts]]></title><description><![CDATA[Ever spent hours wrestling with images that refuse to stay put in your web layouts? You're not alone.
In this comprehensive guide, we will unravel the mystery behind different image centering methods, from the basic and widely used to the more advanc...]]></description><link>https://blog.favouritejome.dev/how-to-center-image-css-for-beautiful-web-layouts</link><guid isPermaLink="true">https://blog.favouritejome.dev/how-to-center-image-css-for-beautiful-web-layouts</guid><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Wed, 03 Apr 2024 15:05:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1712156593514/92e592c1-83ea-4c47-808a-5a727a6bd7b9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ever spent hours wrestling with images that refuse to stay put in your web layouts? You're not alone.</p>
<p>In this comprehensive guide, we will unravel the mystery behind different image centering methods, from the basic and widely used to the more advanced and responsive techniques. Whether you're a seasoned web developer looking to refine your skills or a newcomer eager to understand the nuances of CSS, this article aims to demystify the process of image centering. From margin-based approaches to the flexbox and grid systems, we will navigate through a spectrum of techniques, ensuring that you not only comprehend the concepts but also gain practical insights through illustrative examples.</p>
<p>Let's demystify image centering and empower you to create visually stunning and well-balanced web pages with the precision that CSS provides. We’ll go over 5 methods that can be used to center images.</p>
<h2 id="heading-methods-of-centering-images-in-css">Methods of Centering Images in CSS</h2>
<p>We'll go over these 5 different methods of centering images be it vertically and horizontally, and also the limitations that come with each method.</p>
<ul>
<li><p>Using text-align Property.</p>
</li>
<li><p>Using Margin Property.</p>
</li>
<li><p>Using Flexbox Property.</p>
</li>
<li><p>Using Grid Property.</p>
</li>
<li><p>Using the Position Property.</p>
</li>
</ul>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/mwVNVxpkly0?si=HbtzaD16ZdqzitZh">https://youtu.be/mwVNVxpkly0?si=HbtzaD16ZdqzitZh</a></div>
<p> </p>
<h2 id="heading-method-1-using-text-align-property-to-center-an-image"><strong>Method 1: Using text-align property to Center an Image</strong></h2>
<p>The <strong>text-align</strong> property, although primarily designed for text alignment, can also be a quick and straightforward method to center images horizontally within their container. By applying <strong>text-align: center</strong> to the container, you leverage its alignment capabilities to achieve a centered image without complex CSS rules.</p>
<p>However, this method will only work when the image is wrapped in a block-level container such as a div element, and then on the parent component, the text-align property is used.</p>
<p>Here is a code snippet that shows how to use the text-align property:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Centering an Image with CSS<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container{
   text-align: center;
}

.container img {
   /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/5d5d227d-2c26-4cc5-800d-aae89b9126ba.png" alt="A woman in a yellow sweater taking a photo with a DSLR camera in a park." /></p>
<h3 id="heading-limitation-using-the-text-align-property">Limitation using the text-align property</h3>
<p>However, there are some limitations when using the <strong>text-align</strong> property for centering images:</p>
<ul>
<li><p><strong>Issue of container width</strong>: If the container has a specified width and the image is wider than the container, it won't be centered. In such cases, you might need to ensure that the container is wide enough to accommodate the image.</p>
</li>
<li><p><strong>Issue of Vertical Alignment:</strong> The <strong>text-align</strong> property only handles horizontal alignment. If you need to vertically center the image, you might need additional techniques, such as using Flexbox or CSS Grid properties which will be discussed later on in this guide.</p>
</li>
</ul>
<h2 id="heading-method-2-using-margin-property-to-center-an-image">Method 2: Using Margin property <strong>to Center an Image</strong></h2>
<p>The <strong>margin</strong> property can be used to center an image horizontally within it’s container (parent element). By setting the left and right margins to <strong>auto</strong> and using <strong>text-align: center</strong> as a complementary measure for older versions of Internet Explorer, this method provides a reliable way to achieve image centering.</p>
<p>Here is a code snippet that shows how to use the margin property:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"500"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Centered Image"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
  text-align: center; /* For older versions of IE */
}

.container img {
  display: block; /* Ensures block-level behavior for margins */
  margin-left: auto;
  margin-right: auto;
  /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/2649b5a9-71dd-4428-a050-09c3440bfa58.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/2649b5a9-71dd-4428-a050-09c3440bfa58.png" alt /></p>
<p><strong>Explanation of the above code:</strong></p>
<ul>
<li><p><strong>text-align: center</strong> is used on the container to ensure compatibility with older versions of Internet Explorer. It’s a good practice to add this property in the parent container, but the margin property is well-supported across major browsers now.</p>
</li>
<li><p><strong>display: block</strong> is applied to the image to make it a block-level element, allowing the use of auto margins.</p>
</li>
<li><p><strong>margin-left: auto</strong> and <strong>margin-right: auto</strong> set the left and right margins to auto, effectively centering the image horizontally.</p>
</li>
<li><p><strong>image width</strong> specified as 500px</p>
</li>
</ul>
<h3 id="heading-limitation-of-using-the-margin-property">Limitation of using the margin property</h3>
<ul>
<li><p><strong>Horizontal Centering Only:</strong> The primary limitation of using <strong>margin</strong> for centering is that it only handles horizontal centering. If vertical centering is required, additional techniques or properties need to be employed.</p>
</li>
<li><p><strong>Requires a Defined Width:</strong> The margin: auto; trick relies on the image having a specific width set. Without a defined width, the browser won't have a clear reference for distributing the margins evenly. This can sometimes limit layout flexibility if you need the image to adjust its width dynamically.</p>
</li>
<li><p><strong>Not Ideal for Responsive Design:</strong> While <strong>margin</strong> can be effective for fixed-width layouts, it may not be the best choice for responsive designs. For responsive centering, techniques like Flexbox or CSS Grid are often preferred.</p>
</li>
</ul>
<h2 id="heading-method-3-using-flexbox-property-to-center-images">Method 3: Using Flexbox property <strong>to Center Images</strong></h2>
<p>Flexbox provides a powerful and flexible layout model, making it an excellent choice for centering elements, including images, both horizontally and vertically. By applying the <strong>display: flex;</strong> property to the container and using alignment properties, you can achieve precise control over the positioning of your images.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/K4N5HbituW4">https://youtu.be/K4N5HbituW4</a></div>
<p> </p>
<p>Now, let’s see how to position images to the center using Flexbox both Horizontally and Vertically.</p>
<h3 id="heading-horizontal-centering-with-flexbox">Horizontal Centering with Flexbox</h3>
<p>Here's how you can achieve horizontal centering using Flexbox:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"500"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
  display: flex;
  justify-content: center;
  /* Additional styles for the container, if needed */
}

.container img {
  /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/fd9e1a90-79cd-49c8-b3f2-24a899ea7c54.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/fd9e1a90-79cd-49c8-b3f2-24a899ea7c54.png" alt /></p>
<blockquote>
<p>The border line around the image signifies the container width.</p>
</blockquote>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><strong>display: flex;</strong> is applied to the container, turning it into a flex container.</p>
</li>
<li><p><strong>justify-content: center;</strong> horizontally centers the image within the container.</p>
</li>
<li><p>Additional styles for the container and image can be adjusted based on design requirements.</p>
</li>
</ul>
<hr />
<p>Since the flexbox property stacks the flex items horizontally by default, we could have multiple images in the container positioned horizontally and aligned in the center of the container. Below is an image illustrating this; notice the green border line, which signifies the container width.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/53a60ac9-83fc-4b39-836e-2965e2177256.png" alt /></p>
<p>To achieve the preview above, here's the code snippet</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
      display: flex;
      justify-content: center;
}
</code></pre>
<h3 id="heading-vertical-centering-with-flexbox">Vertical Centering with Flexbox</h3>
<p>To illustrate the vertical centering of images, the flexbox container needs to have a height greater than the image height. Here's how you can achieve vertical centering of an image using Flexbox:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"500"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
  display: flex;
  align-items: center;
  height: 80vh;
  /* Additional styles for the container, if needed */
}

.container img {
  /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/5ea9ad10-c0d5-4d4f-9bea-e0e4f13bf947.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/5ea9ad10-c0d5-4d4f-9bea-e0e4f13bf947.png" alt /></p>
<p><strong>Explanation:</strong></p>
<p>The <strong>align-items: center</strong> property is used here to position the image vertically to the center of the flex container.</p>
<ul>
<li><p><strong>align-items: center;</strong> vertically centers the image within the container.</p>
</li>
<li><p><strong>height;</strong> this property is needed so that the image would be positioned vertically, in the example above 80vh was used but it could be any length value as far as it's greater than the height of the image.</p>
</li>
</ul>
<p>Add more images to the flex container while still using the align-items center property, would look like this.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/2e2c2ad4-0ab6-4a83-9af8-3040e68c7106.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/2e2c2ad4-0ab6-4a83-9af8-3040e68c7106.png" alt /></p>
<h3 id="heading-centering-images-both-horizontally-and-vertically">Centering Images both Horizontally and Vertically</h3>
<p>In the case where there are multiple images and you'd like to center the images vertically and horizontally, here's how to do so:</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/d5cd430a-7b3f-4137-bd6c-f8ab333695bb.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/d5cd430a-7b3f-4137-bd6c-f8ab333695bb.png" alt /></p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */ 
.container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 80vh;
  }
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>The <strong>justify content</strong> property with the value <strong>center</strong> positions the images (or flex items) on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Main_Axis">main axis</a>, that is horizontally, while</p>
</li>
<li><p>The <strong>align-items</strong> property with <strong>center</strong> as its value positions the images vertically on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Cross_Axis">cross-axis</a></p>
</li>
</ul>
<h3 id="heading-advantages-of-using-flexbox-to-center-images"><strong>Advantages of using Flexbox to center images:</strong></h3>
<ol>
<li><p><strong>Simple and Intuitive Syntax:</strong> Flexbox offers a relatively straightforward way to align and distribute elements within a container, making it easier to achieve image centering compared to traditional methods like floats and positioning.</p>
</li>
<li><p><strong>Horizontal and Vertical Centering:</strong> With Flexbox, you can center images both horizontally and vertically within their container using just a few properties. This eliminates the need for workarounds or extra markup.</p>
</li>
<li><p><strong>Responsiveness:</strong> Flexbox layouts are inherently responsive, adapting seamlessly to different screen sizes and device orientations. Your centered images will maintain their alignment across various viewports.</p>
</li>
<li><p><strong>Flexibility for Additional Elements:</strong> Flexbox can handle multiple elements within a container, allowing you to center images alongside text or other content while maintaining a consistent layout.</p>
</li>
<li><p><strong>Control over Distribution and Alignment:</strong> Flexbox provides granular control over the distribution and alignment of items within a flex container. You can fine-tune the spacing and arrangement of images as needed.</p>
</li>
</ol>
<h3 id="heading-limitations-of-using-flexbox-to-center-images"><strong>Limitations of using Flexbox to center images:</strong></h3>
<ol>
<li><p><strong>Potential Nesting Complexity:</strong> When working with complex layouts, nesting Flexbox containers can sometimes lead to unexpected results or make the code harder to maintain. Careful planning is crucial.</p>
</li>
<li><p><strong>Not Ideal for All Scenarios:</strong> Flexbox is not a silver bullet for all layout challenges. For complex image galleries or intricate arrangements, other layout techniques like grid or CSS tables may be more suitable.</p>
</li>
</ol>
<blockquote>
<p>To learn more about using the flexbox properties, please visit the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox">Flexbox MDN documentation</a></p>
</blockquote>
<p>Since we're covering centering images in CSS, why don't you check out <a target="_blank" href="https://purecode.ai/">PureCode.ai</a>; we’ve got over 1000+ AI-generated UI components, which will enable you to skip the tedious work of creating components yourself. Check <a target="_blank" href="https://purecode.ai/">PureCode</a> out today.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/f85058bf-5b98-48bf-a4d8-6900cd3a896d.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/f85058bf-5b98-48bf-a4d8-6900cd3a896d.png" alt /></p>
<h2 id="heading-method-4-using-grid-property-to-center-images">Method 4: Using Grid property <strong>to Center Images</strong></h2>
<p>CSS Grid provides a powerful two-dimensional layout system, making it a versatile choice for centering elements within a container.</p>
<h3 id="heading-horizontal-centering-with-grid">Horizontal Centering with Grid</h3>
<p>Using the Grid property there are various ways to horizontally center an image or images because of the two-dimensional layout system CSS grid provides, but we'll be going over one method since the other process are similar.</p>
<h4 id="heading-using-justify-items-center"><strong>Using justify-items: center</strong></h4>
<p>This approach centers all items, in this case, the image element within the grid container horizontally on their designated lines. Below is an example illustrating how to achieving this:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"100%"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
  display: grid;
  justify-items: center;
  /* Additional styles for the container, if needed */
}

.container img {
  /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/2e7c54f1-5e48-4cee-8c4b-1bc013defba9.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/2e7c54f1-5e48-4cee-8c4b-1bc013defba9.png" alt /></p>
<p><strong>Explanation</strong></p>
<ul>
<li><p>The <strong>display</strong> property as <strong>grid</strong> makes the container selector become a grid container.</p>
</li>
<li><p>The <strong>justify-items</strong> property with the value <strong>center</strong> positions the images (or grid items) on the inline axis, that is horizontally.</p>
</li>
</ul>
<h4 id="heading-horizontal-centering-of-multiple-images-with-grid">Horizontal Centering of <strong>Multiple Images with Grid</strong></h4>
<p>To horizontally align multiple images with the grid property, we'll need to specify the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout#grid_tracks">grid tracks</a> using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns">grid-template-colomns</a> property.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/93019b7f-8952-4402-9957-ec742b8302a6.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/93019b7f-8952-4402-9957-ec742b8302a6.png" alt /></p>
<p>Example code:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
      display: grid;
      grid-template-columns: repeat(2, 1fr); 
      justify-items: center;
}

.container img {
      /* Additional styles for the image, if needed */
 }
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p>The <strong>display: grid</strong> property and value make the container selector a grid container</p>
</li>
<li><p><strong>grid-template-columns: repeat(2, 1fr);</strong> defines the size of the column tracks. In this case, we'll have 1fr unit for two columns, where the two images would reside.</p>
</li>
<li><p><strong>justify-items: center;</strong> positions the images horizontally center within the columns.</p>
</li>
</ul>
<h3 id="heading-vertical-centering-with-grid">Vertical Centering with Grid</h3>
<p>Here is an approach to achieve vertical centering with Grid:</p>
<p><strong>Using align-items: center;</strong></p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
      display: grid;
      align-items: center;
      height: 80vh;
}

.container img {
      /* Additional styles for the image, if needed */
 }
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/ed19127c-20e0-4c81-b370-62e898daa49b.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/ed19127c-20e0-4c81-b370-62e898daa49b.png" alt /></p>
<p><strong>Explanation:</strong></p>
<ul>
<li><p>The <strong>display: grid</strong> property and value make the container selector a grid container</p>
</li>
<li><p>The <strong>align-items</strong> property <strong>center</strong> as its value positions the images vertically on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/align-items">block axis</a></p>
</li>
<li><p><strong>height: 80vh;</strong> is used to show how the image is center vertically.</p>
</li>
</ul>
<p>For multiple images, specifying the <strong>grid-template-columns</strong> property would do the trick.</p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/640c3225-0b94-48f3-a44c-983cb4867821.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/640c3225-0b94-48f3-a44c-983cb4867821.png" alt /></p>
<h3 id="heading-centering-images-both-horizontally-and-vertically-1">Centering Images both Horizontally and Vertically</h3>
<p>Using the <code>place-items: center;</code> properties, which is a shorthand property for the align-items and justify-items properties, would centre images both horizontally and vertically.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- HTML file --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://buffer.com/library/content/images/size/w1200/2023/10/free-images.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Centered Image"</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */
.container {
  display: grid;
  place-items: center;
  /* Additional styles for the container, if needed */
}

.container img {
  /* Additional styles for the image, if needed */
}
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/2d603fb7-e2ae-4358-a48d-a55436e8783b.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/2d603fb7-e2ae-4358-a48d-a55436e8783b.png" alt /></p>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><strong>display: grid;</strong> is applied to the container, establishing it as a grid container.</p>
</li>
<li><p><strong>place-items: center;</strong> is a shorthand property for both <strong>align-items: center;</strong> and <strong>justify-items: center;</strong> effectively centering the content within the grid.</p>
</li>
<li><p>Additional styles for the container and image can be adjusted based on design requirements.</p>
</li>
</ul>
<h3 id="heading-advantages-of-using-grid"><strong>Advantages of Using Grid:</strong></h3>
<ul>
<li><p><strong>Powerful Layout Control:</strong> Grid provides flexible and precise control over the placement of elements within a container.</p>
</li>
<li><p><strong>Multidimensional Layouts:</strong> Grid can handle complex layouts with multiple rows and columns, making it suitable for image galleries or other intricate arrangements.</p>
</li>
</ul>
<h3 id="heading-limitations-of-using-grid"><strong>Limitations of Using Grid:</strong></h3>
<ul>
<li><p><strong>Browser Compatibility:</strong> While modern browsers have excellent support for Grid, older browsers may require fallbacks or polyfills.</p>
</li>
<li><p><strong>Learning Curve:</strong> Grid syntax can be more complex to learn compared to Flexbox, especially for those new to CSS layout techniques.</p>
</li>
</ul>
<h2 id="heading-method-5-using-the-position-property-to-center-images">Method 5: Using the Position property <strong>to Center Images</strong></h2>
<p>The <strong>position property</strong>, along with <strong>top, right, bottom, and left,</strong> can be employed to center an image within its container. While not as flexible as some layout models like Flexbox or Grid, this method provides an alternative for centering when other techniques may not be suitable.</p>
<p>Here's how to achieve centering an image with the position property:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://images.unsplash.com/photo-1660866838821-0c12213703df?ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDEyfHx8ZW58MHx8fHx8&amp;w=1000&amp;q=80"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Centered Image"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-xml">/* CSS file */ 
.container img {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      /* Additional styles for the image, if needed */
  }
</code></pre>
<p><strong>Preview:</strong></p>
<p><img src="https://blogs.purecode.ai/blogs/wp-content/uploads/2024/01/026507b1-c2a1-4603-9318-3aa9dfdaeecf.png" alt /></p>
<p><img src="https://purecode.ai/blogs/wp-content/uploads/2024/01/026507b1-c2a1-4603-9318-3aa9dfdaeecf.png" alt /></p>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><strong>position: relative;</strong> is applied to the container to establish a positioning context for the absolute positioning of the image.</p>
</li>
<li><p><strong>position: absolute;</strong> removes the image from the normal document flow, allowing precise positioning within its nearest positioned ancestor.</p>
</li>
<li><p><strong>top: 50%;</strong> and <strong>left: 50%;</strong> position the image's top-left corner at the center of the container.</p>
</li>
<li><p><strong>transform: translate(-50%, -50%);</strong> centers the image perfectly by adjusting it based on its own dimensions.</p>
</li>
</ul>
<h3 id="heading-advantages"><strong>Advantages:</strong></h3>
<ul>
<li><p><strong>Absolute Precision:</strong> This method allows for precise control over the positioning of the image, making it suitable for unique layout requirements.</p>
</li>
<li><p><strong>Cross-Browser Compatibility:</strong> The approach is widely supported across browsers, including older versions.</p>
</li>
</ul>
<h3 id="heading-limitation-using-the-position-property">Limitation using the Position property</h3>
<ul>
<li><p><strong>Static Container Size:</strong> The container's size needs to be known in advance for accurate centering.</p>
</li>
<li><p><strong>Not as Flexible:</strong> Compared to Flexbox or Grid, this method may require adjustments for responsive designs or dynamic content.</p>
</li>
<li><p><strong>Potential Overlapping:</strong> Be cautious when using absolute positioning to avoid overlapping with other elements.</p>
</li>
</ul>
<h2 id="heading-difference-between-all-5-methods">Difference between all 5 methods</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Method</strong></td><td><strong>Description</strong></td><td><strong>Advantages</strong></td><td><strong>Limitations</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Using text-align Property</strong></td><td>Centrally aligns an image horizontally within its container using <code>text-align: center;</code>.</td><td>– Quick and simple implementation.</td><td></td></tr>
<tr>
<td>- Suitable for basic layouts.</td><td>– Limited to horizontal centering.</td><td></td><td></td></tr>
<tr>
<td><strong>Using Margin Property</strong></td><td>Uses <code>margin: auto;</code> to center an image both horizontally and vertically within its container.</td><td>– Simple and widely supported.</td><td></td></tr>
<tr>
<td>– Supports both horizontal and vertical centering.</td><td>– Requires the image to be a block-level element.</td><td></td><td></td></tr>
<tr>
<td>– Not as flexible for complex layouts.</td><td></td><td></td><td></td></tr>
<tr>
<td><strong>Using Flexbox Property</strong></td><td>Utilizes <code>display: flex;</code> with <code>justify-content: center;</code> and <code>align-items: center;</code> for versatile horizontal and vertical centering.</td><td>– Versatile for both horizontal and vertical centering.</td><td></td></tr>
<tr>
<td>– Great for responsive design.</td><td>– Single-axis limitation.</td><td></td><td></td></tr>
<tr>
<td>– Default behavior of flex items may require additional adjustments.</td><td></td><td></td><td></td></tr>
<tr>
<td><strong>Using Grid Property</strong></td><td>Applies <code>display: grid;</code> to create a two-dimensional layout, providing comprehensive control over image centering.</td><td>– Excellent for complex layouts.</td><td></td></tr>
<tr>
<td>– Precise control over alignment.</td><td>– Learning curve for advanced features.</td><td></td><td></td></tr>
<tr>
<td>– May require vendor prefixes for older browser compatibility.</td><td></td><td></td><td></td></tr>
<tr>
<td><strong>Using Position Property</strong></td><td>Utilizes <code>position: absolute;</code> with <code>top: 50%;</code>, <code>left: 50%;</code>, and <code>transform: translate(-50%, -50%);</code> for precise centering of an image relative to its container.</td><td>– Absolute precision in centering.</td><td></td></tr>
<tr>
<td>– Suitable for unique layout requirements.</td><td>– Requires knowledge of container dimensions.</td><td></td><td></td></tr>
<tr>
<td>– May not be as flexible for responsive designs.</td><td></td><td></td></tr>
</tbody>
</table>
</div><h2 id="heading-frequently-asked-questions">Frequently Asked Questions</h2>
<h3 id="heading-how-do-i-center-images-in-css">How do I center images in CSS?</h3>
<p>You can center images using any of these methods</p>
<ul>
<li><p><strong>Flexbox</strong> is often preferred for its simplicity and responsiveness.</p>
</li>
<li><p><strong>Grid</strong> is powerful for complex layouts and multiple images.</p>
</li>
<li><p><strong>Text-align</strong> is quick for basic horizontal centering.</p>
</li>
<li><p><strong>Auto margins</strong> are useful for images with known widths.</p>
</li>
<li><p><strong>Position property</strong> offers precise control but requires more understanding.</p>
</li>
</ul>
<h3 id="heading-how-do-i-center-an-absolute-image-in-a-div">How do I center an absolute image in a div?</h3>
<ul>
<li><p>Using the <strong>Position and Transform</strong> if you need precise control over the image's absolute positioning within the div.</p>
</li>
<li><p>Consider <strong>Flexbox or Grid</strong> when you want simplicity and responsiveness, especially if centering other elements alongside the image.</p>
</li>
</ul>
<h2 id="heading-final-thoughts-on-centering-images-with-css"><strong>Final thoughts on Centering Images with CSS</strong></h2>
<p>Congratulations on completing this journey through various CSS techniques for image centering! By now, you've gained insights into different methods, each offering its unique advantages. Demystifying image centering with CSS opens up a world of possibilities for creating visually appealing and well-structured web designs. Whether you're a beginner or an experienced developer, mastering these techniques empowers you to tackle diverse design challenges with confidence.</p>
<p>Check out <a target="_blank" href="https://purecode.ai/">Purecode.ai</a> today, for streamlining front-end code creation.</p>
]]></content:encoded></item><item><title><![CDATA[Tailwind CSS just got better!]]></title><description><![CDATA[Tailwind CSS recently launched some awesome updates in v3.4, supporting CSS features like Dynamic viewport units, subgrid supports and other features, which we'll go over in this article.
It's so easy to be carried away by using the already-known fea...]]></description><link>https://blog.favouritejome.dev/tailwind-css-just-got-better</link><guid isPermaLink="true">https://blog.favouritejome.dev/tailwind-css-just-got-better</guid><category><![CDATA[Tailwind CSS]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sun, 31 Mar 2024 22:19:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711923463206/56e95848-606b-40e5-abdd-0c1c69d382ab.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Tailwind CSS recently launched some awesome updates in v3.4, supporting CSS features like Dynamic viewport units, subgrid supports and other features, which we'll go over in this article.</p>
<p>It's so easy to be carried away by using the already-known features a tool provides without bothering to know the newly added features, in this case, Tailwind CSS. As a Tailwind CSS fanboy myself, I barely try out the new updates happening in CSS since I mainly use Tailwind; however, when those new updates get to TailwindCSS, it's a game-changer since I can now easily make use of them.</p>
<h2 id="heading-dynamic-viewport-units"><strong>Dynamic viewport units</strong></h2>
<p>Making a full-height viewport on mobile devices with the <code>vh</code> unit wasn't the best because the mobile browser's toolbar usually gets in the way of the viewport, allowing the layout to bleed out. Illustrated below:</p>
<p><a target="_blank" href="https://web.dev/blog/viewport-units#the-need-for-new-viewport-units"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711917443289/ed072f16-7483-4cb5-bf8e-b143a97ffec4.png" alt class="image--center mx-auto" /></a></p>
<blockquote>
<p>Source: <a target="_blank" href="https://web.dev/blog/viewport-units#the-need-for-new-viewport-units">https://web.dev/blog/viewport-units#the-need-for-new-viewport-units</a></p>
</blockquote>
<p>However, when the viewport is scrolled down, the <code>vh</code> unit works as expected cause now the browser's toolbar is retracted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711917688457/382105bc-169f-4f9b-bdc3-da37ace075ab.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>Source: <a target="_blank" href="https://web.dev/blog/viewport-units#the-need-for-new-viewport-units">https://web.dev/blog/viewport-units#the-need-for-new-viewport-units</a></p>
</blockquote>
<p>To combat this issue, new viewport units were added to CSS, namely Large viewport, Small viewport and Dynamic viewport, having the prefix <code>lv</code>, <code>sv</code>, <code>dv</code> respectively. Dynamic viewport units are essentially the combination of both small and large viewport units.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711918931569/a89c173d-8ff4-44b3-bd60-f20d5e4c70c7.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>Source: <a target="_blank" href="https://web.dev/blog/viewport-units">https://web.dev/blog/viewport-units</a></p>
</blockquote>
<p>Here are some dynamic viewport units added to Tailwind CSS by default <code>w-svw</code>, <code>w-lvw</code>, <code>w-dvw</code>, <code>h-svh</code>, <code>h-lvh</code>, <code>h-dvh</code> and arbitrary values like this <code>min-h-[75dvh]</code> works as well 🤩.</p>
<h2 id="heading-has-pseudo-class">:has() pseudo-class</h2>
<p>The <code>:has()</code> pseudo-class is one of those cool features recently added to CSS that I haven't got to play a lot with; since it's now supported in Tailwind CSS, it just opens a new world of possibilities 🤯.</p>
<p><em>The</em><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/:has"><code>:has()</code><em>pseudo-class</em></a><em>allows you to style an element based on its children, not just based on its parents. It even makes it possible to style based on subsequent siblings - From the</em><a target="_blank" href="https://play.tailwindcss.com/yuQyHjiuSx"><em>Tailwind CSS blog</em></a></p>
<p>Essentially, think of the <code>:has()</code> pseudo-class as a shortcut and a better way to do some crazy things you might have done with SASS or JavaScript but now can be done with plain CSS or, in this case, Tailwind CSS 🤩</p>
<p>Here's a silly example to illustrate how the <code>:has()</code> pseudo-class work, in this case, if the child element (<code>img</code>) is next to a paragraph then the background of the parent element changes to red.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711922504420/969f1f1b-abee-4dc0-ba81-b81eab6032fc.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"has-[img+p]:bg-red-400"</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-4"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"..."</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-4"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"..."</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<blockquote>
<p>Preview code example here: <a target="_blank" href="https://play.tailwindcss.com/FDBP3zqjoS">https://play.tailwindcss.com/FDBP3zqjoS</a></p>
<p>Here's a guide showing ten practical examples that utilizes the CSS :has selector: <a target="_blank" href="https://bejamas.io/blog/learn-css-has-selector-by-examples-top-use-cases/">https://bejamas.io/blog/learn-css-has-selector-by-examples-top-use-cases/</a></p>
</blockquote>
<h2 id="heading-the-variant">The * variant</h2>
<p>The * variant is a blessing from Tailwind CSS, allowing us to now style children's elements from the parent using utility classes. Here's a code example and preview of how it works:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711921397770/ab1d69d8-1ee2-4917-825b-88308dd520b4.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Categories:<span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"*:rounded-full *:border *:border-sky-100 *:bg-sky-50 *:px-2 *:py-0.5 dark:text-sky-300 dark:*:border-sky-500/15 dark:*:bg-sky-500/10 ..."</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Sales<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Marketing<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>SEO<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- ... --&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<blockquote>
<p>Preview code example here: <a target="_blank" href="https://play.tailwindcss.com/yuQyHjiuSx">https://play.tailwindcss.com/yuQyHjiuSx</a></p>
</blockquote>
<h2 id="heading-the-size-utilities">The size-* utilities</h2>
<p>The <code>size-*</code> utilities allow you to set the width and height at the same time, which is very useful when working with icons or avatars.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711920173529/9bc51c73-7891-440b-b37f-4eabf4cfce9a.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex gap-6 items-end"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"size-14 rounded-full"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://avatars"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"size-20 rounded-full"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://avatars"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"size-24 rounded-full"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://avatars"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<blockquote>
<p>Preview code example here: <a target="_blank" href="https://play.tailwindcss.com/NawRNldMH4">https://play.tailwindcss.com/NawRNldMH4</a></p>
</blockquote>
<hr />
<p>Well, that rounds it up for the newly added exciting features in Tailwind CSS, there are a bunch of other cool updates that came with v3.4, do check out the <a target="_blank" href="https://tailwindcss.com/blog/tailwindcss-v3-4">blog announcement</a>.</p>
<p>To get started with these new features, upgrade your projects by installing the latest version of <code>tailwindcss</code> from npm:</p>
<pre><code class="lang-bash">$ npm install tailwindcss@latest
</code></pre>
<h2 id="heading-references">References</h2>
<ul>
<li><p><a target="_blank" href="https://web.dev/blog/viewport-units">Web.dev - The large, small, and dynamic viewport units</a></p>
</li>
<li><p><a target="_blank" href="https://www.smashingmagazine.com/2023/12/new-css-viewport-units-not-solve-classic-scrollbar-problem/">New CSS Viewport Units Do Not Solve The Classic Scrollbar Problem</a></p>
</li>
<li><p><a target="_blank" href="https://tailwindcss.com/">TailwindCSS</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Why learn Next.js if I already know React.js?]]></title><description><![CDATA[As a beginner in the web ecosystem, it could be overwhelming to learn new tools cause there's just a lot to learn and if you've learned a tool that works, why migrate to another, right?
Well, there could be so many reasons, and In this article, we'll...]]></description><link>https://blog.favouritejome.dev/why-learn-nextjs-if-i-already-know-reactjs</link><guid isPermaLink="true">https://blog.favouritejome.dev/why-learn-nextjs-if-i-already-know-reactjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Thu, 31 Aug 2023 20:22:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693452955520/593f7cb1-8235-496e-b666-c25c2fa129e9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a beginner in the web ecosystem, it could be overwhelming to learn new tools cause there's just a lot to learn and if you've learned a tool that works, why migrate to another, right?</p>
<p>Well, there could be so many reasons, and In this article, we'll go over 3 reasons why learning Next.js is the next best thing to do after getting the fundamentals of React.js down.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you're not certain you're ready to learn Next.js yet, watch this video by <a target="_blank" href="https://www.youtube.com/@PedroTechnologies">PedroTech</a> - (<a target="_blank" href="https://youtu.be/wd639F9aKU0?si=RiPUCVVruEAv4ElZ">What You Need to Know Before Learning NextJS</a>).</div>
</div>

<h2 id="heading-prerequisites-and-expectation">Prerequisites and Expectation</h2>
<ul>
<li><p>Good foundation with React.js</p>
</li>
<li><p>An Introduction to what Next.js offers but not the full gist 😅</p>
</li>
<li><p>Beginner-friendly and assumes the reader doesn't know much about Next.js</p>
</li>
<li><p>Assumes questions a newbie to Next.js might ask.</p>
</li>
</ul>
<h2 id="heading-introduction-to-nextjs">Introduction to Next.js</h2>
<p>Next.js is a React framework for building full-stack web applications <a target="_blank" href="https://nextjs.org/docs"><em>(referenced from the Next.js documentation)</em></a><em>.</em></p>
<p><a target="_blank" href="https://nextjs.org/docs"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693439562676/296be42e-8275-4a9b-ac78-54d7dd7f7b64.png" alt class="image--center mx-auto" /></a></p>
<p>Now, you might have questions like:</p>
<blockquote>
<p>What does React framework mean? also,<br />I'm still new to React, I don't want to build full-stack web applications yet 😕</p>
</blockquote>
<p>Next.js, being a React framework, simply means there are additional features, optimizations and guidelines to follow that make development easy compared to plain React.js, which is unopinionated about how routing should be done, for example.</p>
<p>As for building <strong>full-stack</strong> web applications, as a newbie you don't need to bother about that; with time and lots of practice, you'll join the train in building full-stack applications.</p>
<h2 id="heading-why-learn-nextjs">Why learn Next.js?</h2>
<p>From the introduction of Next.js, I assume you can tell that Next.js is for building large applications, usually applications with multiple pages, with complex functionalities and not just a todo app, which is usually everyone's big project learning React.</p>
<blockquote>
<p>Even I built a todo app, some years ago, oh fun memories 😄.</p>
<p>If you'd like to read about my journey building a todo app which felt like a big project then, here's the article - (<a target="_blank" href="https://favouritejome.hashnode.dev/2-months-of-learning-reactjs-and-the-project-i-worked-on">2 months of Learning React.js and The project I worked on</a>)</p>
</blockquote>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The reasons below aren't in any particular other</div>
</div>

<h3 id="heading-routing-between-pages">Routing Between Pages</h3>
<p>Coming from React.js, when you have to build a web application that has multiple pages, e.g. an e-commerce website, we make use of <a target="_blank" href="https://reactrouter.com/en/main">React Router</a> or other routers for React.</p>
<p>All the routes would be listed in the entry point of the React app in order to emulate a Multi-Page Application (MPA) behaviour while React uses a Single Page Application (SPA) architecture.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you're confused by MPA and SPA, read this article <a target="_blank" href="https://blog.openreplay.com/single-page-apps-vs-multiple-page-apps/">SPA vs MPA</a> to gain some insight.</div>
</div>

<p>In Next.js, routing between pages is really easy, and you don't have to define the structure of the router, you just follow the guidelines Next.js provides about folder structures. So essentially Next.js uses a file-system router.</p>
<p>However, at the point of writing this article, Next.js has two means of handling routing, the first means being the <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/routing"><strong>Pages Router</strong></a> and the second the <a target="_blank" href="https://nextjs.org/docs/app/building-your-application/routing"><strong>App Router</strong></a>.</p>
<p>Both the Pages Router and the App Router work excellently though very differently and the in-depth differences between the routers are beyond the scope of this article 😅</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you're just getting started learning Next.js, I strongly recommend learning about the <strong>Pages Router</strong> first before the app router, cause lots of applications, and tutorials use the Pages router.</div>
</div>

<p>Here's an example of how routes would be defined in a React app, using React Router v6.15.0</p>
<p><a target="_blank" href="https://reactrouter.com/en/main/start/concepts#defining-routes"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693443139676/4dd32680-9b7b-40ff-bda3-56148bfe5a9c.png" alt class="image--center mx-auto" /></a></p>
<p>For Next.js, here's how the routes are defined in both the App and Pages Router using the file-system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693510220233/1dd501df-a6c6-4477-8669-71e36cd487eb.png" alt class="image--center mx-auto" /></p>
<p>Though it might look like lots of folders, but trust me, it's so much better 🤩.</p>
<h3 id="heading-optimizations">Optimizations</h3>
<p>Hmm, optimizations, should I care about optimizations if I'm a newbie to Next.js and React?</p>
<p>Well, yes and no 😅</p>
<p>No, because you're still learning, and Yes because at some point you'd have to care about optimizations to make your app faster.</p>
<p>Optimations in Next.js come in various forms, but the essence of optimation is to improve the application speed and <a target="_blank" href="https://web.dev/vitals/">Core Web Vitals</a>.</p>
<blockquote>
<p>Since this article to geared towards newbies with Next.js, we'll not be going into all the optimization patterns Next.js provides but just two, that is Metadata and Image optimization.</p>
</blockquote>
<h4 id="heading-metadata-search-engine-optimization-seo"><strong>Metadata - Search Engine Optimization (SEO)</strong></h4>
<p>Metadata is used to add helpful content about a web application, helping Search Engines like Google crawl and index the web application. Metadata isn't just for Search engines, social media also reflects metadata information of the site.</p>
<blockquote>
<p>For example, the image below shows the metadata information for <a target="_blank" href="https://aichatbot.so/">https://aichatbot.so/</a></p>
<p><a target="_blank" href="https://aichatbot.so/"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693448079238/baf7e710-35c0-4e73-a321-b1368fc95a6e.png" alt="AIchatbot.so" class="image--center mx-auto" /></a></p>
</blockquote>
<p>Coming from React, managing metadata information isn't good at all, Well, there is this library <a target="_blank" href="https://www.npmjs.com/package/react-helmet-async"><strong>react-helmet-async</strong></a> which helps in some ways but it's no way compared to Next.js benefits.</p>
<p>If you'd like to know why React is bad for SEO, please go through these guides:</p>
<ul>
<li><p><a target="_blank" href="https://youtu.be/j8OUmE4Vj3M?si=8KSJmJ784NUPPi1E">SEO For React Developers</a> by <a target="_blank" href="https://www.youtube.com/@codedamn">Codedamn</a> <strong>(recommended guide)</strong></p>
</li>
<li><p><a target="_blank" href="https://www.techmagic.co/blog/react-seo/#:~:text=React%2C%20out%20of%20the%20box,for%20both%20users%20and%20SEO.">Is React Good for SEO? The Complete Guide in 2023</a></p>
</li>
</ul>
<p>In Next.js, Metadata can be handled in two ways due to the Routers, i.e., the Pages and App Router.</p>
<p>Below is an example of how metadata is defined in Next.js:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693451013389/ad474693-f7ca-4534-91a5-edafc0aa4bff.png" alt="aichatbot.so metadata" class="image--center mx-auto" /></p>
<p>To learn more about Metadata in Next.js please visit the documentation:</p>
<ul>
<li><p><a target="_blank" href="https://nextjs.org/docs/app/building-your-application/optimizing/metadata">App Router docs - Metadata</a></p>
</li>
<li><p><a target="_blank" href="https://nextjs.org/docs/pages/api-reference/components/head">Pages Router docs - Metadata</a></p>
</li>
</ul>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you'd like to know more about metadata, read this guide - <a target="_blank" href="https://web.dev/learn/html/metadata/">Learn about Metadata</a></div>
</div>

<h4 id="heading-image-optimization"><strong>Image Optimization</strong></h4>
<p>In Next.js, if you make use of the built-in image component, you get all the benefits of image optimizations.</p>
<p>Why do I need image optimization, you might ask?</p>
<p>Well, from the <a target="_blank" href="https://nextjs.org/docs/app/building-your-application/optimizing/images">Next.js documentation about images</a> here are the benefits you get using the Image component.</p>
<ul>
<li><p><strong>Size Optimization:</strong> Automatically serve correctly sized images for each device, using modern image formats like WebP and AVIF.</p>
</li>
<li><p><strong>Visual Stability:</strong> Prevent <a target="_blank" href="https://nextjs.org/learn/seo/web-performance/cls">layout shift</a> automatically when images are loading.</p>
</li>
<li><p><strong>Faster Page Loads:</strong> Images are only loaded when they enter the viewport using native browser lazy loading, with optional blur-up placeholders.</p>
</li>
<li><p><strong>Asset Flexibility:</strong> On-demand image resizing, even for images stored on remote servers</p>
</li>
</ul>
<blockquote>
<p>Hmm, what does visual stability mean, and the other benefits listed above 😕</p>
<p>To answer that question, I suggest watching this video which explains and shows you the benefits - <a target="_blank" href="https://youtu.be/IU_qq_c_lKA?si=9fDvfdoUPy_DvIY-"><strong>Using Images in Next.js (next/image examples)</strong></a> by <a class="user-mention" href="https://hashnode.com/@leerob">Lee Robinson</a></p>
</blockquote>
<h3 id="heading-data-fetching">Data Fetching</h3>
<p>Hmm, Data Fetching, but I can fetch data using the fetch API in React and also use a library like <a target="_blank" href="https://www.npmjs.com/package/axios">Axios</a>, and they all work fine.</p>
<p>Yes, using the fetch API and Axios works just fine, but with Next.js you get data-fetching features on steroids 🤩. Let's go over an example to get a feeling on how Data fetching in Next.js is really cool.</p>
<p>Let's say you're working on an E-commerce website with plain React, and on the product details page you have a single component responsible for the UI on that page cause it's basically going to be the same across all products.</p>
<p>Pictures speak better than words or text in this case, so below is an image showing two different products (shoes) with similar contents.</p>
<p><a target="_blank" href="https://www.jumia.com.ng/"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693491132163/391ab6d7-4093-47f6-a38c-2161de458e96.png" alt="Jumia product page" class="image--center mx-auto" /></a></p>
<p>Let's also assume the product details are coming from some API, and to get this to work in React, you'll have to fetch the data on the client (known as <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side"><strong>Client-side fetching</strong></a>), whereby the user will get to the page first, and you probably show a loading state and then when the fetch resolves and the data is then displayed on the page.</p>
<p>The downside to this approach with React (<a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side"><strong>Client-side fetching</strong></a>), is that:</p>
<ul>
<li><p>The page wouldn't have the HTML structure for the product page, which is bad for SEO</p>
</li>
<li><p>Also, when a particular product page is visited multiple times, there will always have to be a request to the API, getting the same data again and again.</p>
</li>
</ul>
<p>Now, let's see how Next.js solves this problem.</p>
<blockquote>
<p>In Next.js there are a lot of Data Fetching patterns depending on the different use cases, but in this article, we wouldn't go over all the Data fetching patterns or techniques, we'll just go over the broad scope of how Next.js make data fetching better.</p>
</blockquote>
<p>To solve the problem of the HTML structure not being in the shape of the E-commerce product page, Next.js does something called <strong>pre-rendering.</strong> From Next.js docs, Pre-rending is the process of generating HTML for each page in advance.</p>
<p><a target="_blank" href="https://nextjs.org/learn/basics/data-fetching/pre-rendering"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693496608990/9d6e1852-282e-49c8-af53-5d2152e745bd.png" alt class="image--center mx-auto" /></a></p>
<p>To solve the issue of always fetching the data when a page is visited, Next.js provides some data fetching patterns that can tackle this problem.</p>
<p>In the App router, we have <a target="_blank" href="https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md">React Server Components</a> and <a target="_blank" href="https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations">Server Action</a> while with the Pages router, we have <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-props">getStaticProps</a>, <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props">getServerSideProps</a>, <a target="_blank" href="https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths">getStaticPaths</a> and more, which are grouped into two forms <a target="_blank" href="https://nextjs.org/docs/basic-features/pages#static-generation-recommended">Static Generation</a> and <a target="_blank" href="https://nextjs.org/docs/basic-features/pages#server-side-rendering">Server-side Rendering</a> 🤯🤯🤯🤯</p>
<blockquote>
<p>OMG, what's all this for data fetching 😭</p>
<p>Data Fetching is kind of scary in Next.js from all the Data fetching patterns it has.</p>
</blockquote>
<p>Well, the good thing is that as a newbie in Next.js, you don't need to understand all just yet.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">A good guide that'll go over all this data-fetching craziness 😮‍💨 - <a target="_blank" href="https://nextjs.org/learn/basics/data-fetching">Pre-rendering and Data Fetching</a> by the Next.js team.</div>
</div>

<p>The best Next.js data fetching pattern for the product details would be Static Generation, using the getStaticProps function on the Pages Router, which basically generates several HTML files for the product details page depending on the data from the backend API and then those HTML files are reused on the client, and cached in some Content Delivery Network (CDN), so there's no additional call to the server after build time.</p>
<p><a target="_blank" href="https://nextjs.org/learn/basics/data-fetching/two-forms"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693511253461/d7f5a9c0-f30b-4c87-9eaf-32768031bfb5.png" alt="Static Generation " class="image--center mx-auto" /></a></p>
<p>As for the App router, the same thing happens, but we'll make use of server components which is the only option and they are amazing 🤩.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you don't understand all that was mentioned about Data Fetching, it's totally fine. I've left useful resources below, to guide you learn Next.js for free.</div>
</div>

<h2 id="heading-conclusion">Conclusion</h2>
<p>I'd like to believe I've been able to convince you and not confuse you 😏, that learning Next.js is the next thing you need to do in other to advance your React skills. Another motivation could be the Job market, most companies make use of some framework, be it Next.js, Remix and so many others out there. So learn a React framework, cause even the <a target="_blank" href="https://react.dev/learn/start-a-new-react-project#nextjs-app-router">React docs</a> says so.</p>
<p><a target="_blank" href="https://react.dev/learn/start-a-new-react-project#nextjs-app-router"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693513046940/34120b7c-bf3d-4c77-942f-707145d12a19.png" alt class="image--center mx-auto" /></a></p>
<p>Finally, I'd like to say a big thank you to my friend <a class="user-mention" href="https://hashnode.com/@Jesugbogo">Enis Jesugbogo</a> for making me write this article speedily😅, by encouraging me to write before August 2023 is over, some hours left before the new month, so I hope Enis you're proud 😂.</p>
<p>Also, to all my readers, I promise to write from time to time now, Thanks for sticking around, much appreciation 💖</p>
<h2 id="heading-helpful-resources-learning-nextjs">Helpful Resources Learning Next.js</h2>
<p>Disclaimer: Please learn about the Pages Router before the App Router if you're just getting started with Next.js. Then as you improve on yourself, look into the App router.</p>
<ol>
<li><p><a target="_blank" href="https://nextjs.org/learn/foundations/about-nextjs">Next.js Learning Documentation</a> - The Next.js team were kind enough to put up this guide, that I followed to learn Next.js, though some things might have changed as to when I went through it, but it's a good place to start from. <strong>Highly recommended. 🤩</strong></p>
</li>
<li><p><a target="_blank" href="https://youtube.com/playlist?list=PL4cUxeGkcC9g9gP2onazU5-2M-AzA8eBw&amp;si=6yRUcBP8fmiRppeQ"><strong>Next.js Tutorial for Beginners (2020)</strong></a> - by the <a target="_blank" href="https://www.youtube.com/@NetNinja">Net Ninja</a>. This is a video guide which is quite old but it really teaches Next.js Pages Router principles really well. BTW, I just love learning new technologies from <a target="_blank" href="https://www.youtube.com/@NetNinja">Net Ninja</a>, cause I love his teachings 😍</p>
</li>
<li><p><a target="_blank" href="https://youtube.com/playlist?list=PL4cUxeGkcC9jZIVqmy_QhfQdi6mzQvJnT&amp;si=Y-CCK9Cy4q9TRCy0"><strong>Next 13 Crash Course 2023</strong></a> - by the <a target="_blank" href="https://www.youtube.com/@NetNinja">Net Ninja</a>. I haven't gone through it myself, but I'm sure it's great 💖</p>
</li>
<li><p><a target="_blank" href="https://nextjs.org/docs"><strong>Next.js Documentation</strong></a> <strong>-</strong> by the Next.js team. Though I don't recommend this documentation for learning, cause it doesn't work you through building an actual application. The documentation is useful when you want to know everything about some features with all the APIs and so on. 😊</p>
</li>
</ol>
<p>With all of that, all the best learning Next.js, cheers 🍻 and see you in the next article 🎉</p>
]]></content:encoded></item><item><title><![CDATA[Overcoming Challenges When Moving from Create React App (CRA) to Vite: Debugging Tips]]></title><description><![CDATA[At my work, we have a reasonably large codebase using Create React App (CRA) and the codebase started feeling slow, starting up the server took forever, and hot module reload took forever to reflect changes on the browser also, so at that point, I kn...]]></description><link>https://blog.favouritejome.dev/overcoming-challenges-when-moving-from-create-react-app-cra-to-vite-debugging-tips</link><guid isPermaLink="true">https://blog.favouritejome.dev/overcoming-challenges-when-moving-from-create-react-app-cra-to-vite-debugging-tips</guid><category><![CDATA[DebuggingFeb]]></category><category><![CDATA[ #DebuggingFeb Writeathon]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Wed, 08 Mar 2023 18:20:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678296189061/1f472db1-8ab6-4587-9ffd-8d7e0262ea9b.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At my work, we have a reasonably large codebase using Create React App (CRA) and the codebase started feeling slow, starting up the server took forever, and hot module reload took forever to reflect changes on the browser also, so at that point, I knew I had to move to the <strong>Next Generation Frontend Tooling - Vite 🔥</strong></p>
<p>In this article, I'll go over the 5 challenges I encountered while migrating from CRA to Vite and updating dependencies, how I found solutions to the challenges and some Vite-specific things that just had to be done.</p>
<p>Please note that this article is centred on the libraries which my work codebase uses, so it might not cover all possible errors, you might encounter will migrating from CRA to Vite. Some of the libraries mentioned in the article and used in the codebase are:</p>
<ul>
<li><p><a target="_blank" href="https://mui.com/">MUI</a></p>
</li>
<li><p><a target="_blank" href="https://reactjs.org/">React</a></p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/react-phone-input-2">React-phone-input-2</a></p>
</li>
<li><p>e.t.c</p>
</li>
</ul>
<hr />
<h2 id="heading-context-before-successfully-migrating-to-vite">Context before Successfully Migrating to Vite</h2>
<p>Before I successfully migrated from CRA to Vite, I had failed in the past and given up because of the pill of errors I encountered. The way started the process of migrating was by finding articles about the migration process and following them, step by step, yet I ended up with errors the articles didn't account for.</p>
<p>So I decided to go with the divide-and-conquer approach (without recursion 😏), by initializing a Vite project from scratch and setting up the project gradually, while adding new necessary files from the CRA codebase to the Vite codebase.</p>
<p>Essentially, I had two branches managed by git, one for the codebase with CRA and another with Vite. The Vite branch was pulled from the CRA branch but then all the files were deleted to initiali<a target="_blank" href="https://github.com/vitejs/vite/issues/769">z</a>e the Vite application.</p>
<blockquote>
<p>There might have been a better way for this process, but that's what I did, and it's tedious but it works 🤧</p>
</blockquote>
<hr />
<h2 id="heading-challenges-and-errors-i-encountered">Challenges and Errors I encountered</h2>
<h3 id="heading-1-the-jsx-syntax-extension-is-not-currently-enabled">1. The JSX syntax extension is not currently enabled</h3>
<p>The very first error I encountered was: <strong>The JSX syntax extension is not currently enabled</strong> which means that if you have a file that has a React component that returns JSX, then the file extension should be <strong>.jsx</strong> and not <strong>.js.</strong></p>
<p>Here's how the error shows on the terminal:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1677716627119/e5722fcc-7295-4880-ae11-b4561326f618.png" alt class="image--center mx-auto" /></p>
<p>All the files in the codebase were using <strong>.js</strong> as the file extension and now Vite was saying I have to move 50+ files to <strong>.jsx</strong> 🤯.</p>
<p>Evan You, the creator of Vite, gave a good reason why <strong>.jsx</strong> extension should be used with files that return JSX. The response from Evan You was mentioned in the issue: <a target="_blank" href="https://github.com/vitejs/vite/issues/769">Add an option to transpile .js file with build · Issue #769</a>.</p>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/769#issuecomment-780593283"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1677717208376/e5fd9239-7f8f-4bbe-a6b4-65ac895ba8b2.png" alt="Evan You Response To: Add an option to transpile .js file with esbuild" class="image--center mx-auto" /></a></p>
<h3 id="heading-solution">Solution</h3>
<p>The way I overcame this challenge was by using a tool called <a target="_blank" href="https://learn.microsoft.com/en-us/windows/powertoys/"><strong>PowerToys</strong></a> created by Microsoft. It comes with a feature named <strong>PowerRename,</strong> which allowed me to rename multiple file extensions at the same time quickly. So I renamed all the file extensions from <strong>.js</strong> to <strong>.jsx</strong> provided the file contains some form of JSX being returned.</p>
<blockquote>
<p>Visit here to learn about the feature PowerRename offers: <a target="_blank" href="https://learn.microsoft.com/en-us/windows/powertoys/powerrename">PowerToys PowerRename utility for Windows | Microsoft Learn</a></p>
</blockquote>
<h3 id="heading-2-upgrading-dependencies-in-the-codebase">2. Upgrading dependencies in the codebase</h3>
<p>Since I was already making a large change to the codebase, by migrating from CRA to Vite, I thought to myself, why not update all the dependencies to the latest and greatest version?</p>
<p><em>Honestly, I don't know who sent me to do this, cause it ended up being a terrible experience 🤣</em></p>
<p>One of the dependencies that had lots of breaking changes was Material UI now called MUI. Before upgrading, Material UI v4.11.2 was used in the codebase along with some of its peer dependencies like Material Icons around similar versions.</p>
<p>Upgrading to MUI v5 introduced a lot of changes, to where components were imported from, all the packages' import names were changed from <code>@material-ui/*</code> to <code>@mui/*,</code> and many more changes.</p>
<p>I mean, just look at this mess MUI put me through 😅</p>
<p><a target="_blank" href="https://mui.com/material-ui/migration/migration-v4/#replace-all-imports"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678268478242/08657db3-3571-42af-8325-a6227ccda445.png" alt class="image--center mx-auto" /></a></p>
<p>Other dependencies had some changes too, which I had to implement due to the upgrade, but none was as stressful as MUI, hence, I'm only mentioning MUI in this section.</p>
<p>Another problem that came with upgrading Material UI was changes to where components are imported from. For example, the Button component in Material UI v4 is imported from <code>@material-ui/core/</code> while MUI v5 is from <code>@mui/material/</code>. So I had to be aware, that not only the prefix <code>@material-ui/</code> was changed but also</p>
<p><em>Material UI v4 example for the Button component:</em></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">'@material-ui/core/Button'</span>;
<span class="hljs-comment">// ----------------- OR -------------------- //</span>
<span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'@material-ui/core'</span>;
</code></pre>
<p><em>MUI v5 example for the Button component:</em></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">'@mui/material/Button'</span>;
<span class="hljs-comment">// ----------------- OR -------------------- //</span>
<span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mui/material'</span>;
</code></pre>
<p>So how did I overcome the changes that MUI brought?</p>
<blockquote>
<p>I failed to upgrade from React 17 to 18 in my work codebase because I wasn't ready for the stress, especially now that components are rendered twice and I might need to change the architecture of how useEffect is used 😏.</p>
<p>Maybe I'll do this later in the future... 😤</p>
</blockquote>
<h3 id="heading-solution-1">Solution</h3>
<p>There was no way I could go over 500+ files that depended on Material UI and change them to the new MUI structure manually. To overcome this challenge, I relied on VS Code Search and Replace feature.</p>
<p>From the image below, you'll see that 601 files had the word <strong>@material-ui/</strong>, which needed to be replaced with <strong>@mui/</strong>. Luckily for me VS Code did the replacement in a bliss.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678271655654/c33dc8fe-57ee-482c-a60c-9c0b1cb3a036.png" alt class="image--center mx-auto" /></p>
<p>Using the Search and Replace feature in VS Code, I was able to quickly make global fixes on the codebase.</p>
<p>Reading the documentation for the dependencies I upgrade was a huge help, like documentation of MUI has a migration step, so I was aware of the breaking changes, which can be found here: <a target="_blank" href="https://mui.com/material-ui/migration/migration-v4/#replace-all-imports">Migrating to v5: getting started - Material UI (</a><a target="_blank" href="http://mui.com">mui.com</a><a target="_blank" href="https://mui.com/material-ui/migration/migration-v4/#replace-all-imports">)</a>.</p>
<h3 id="heading-3-error-minified-react-error">3. Error: Minified React error</h3>
<p>The error <strong><em>Minified React error</em></strong> was caused by the library <a target="_blank" href="https://www.npmjs.com/package/react-phone-input-2"><code>react-phone-input-2</code></a> used in the codebase. This error was also one that gave me a tough time, to figure out, cause it worked fine on the development server but shows the error on production.</p>
<p>The root of the error, explained by data is that many packages follow a bad practice that breaks Rollup ESM-CJS interop.</p>
<blockquote>
<p>Truthfully, I don't know enough about how Vite works with Rollup, and how libraries are made, so I'll direct you to the root of this error, explained data here <a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1024852072">https://github.com/vitejs/vite/issues/2139#issuecomment-1024852072</a></p>
</blockquote>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1024852072"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678278432335/e09f0f19-d6ae-41ad-80ea-a692465b102c.png" alt class="image--center mx-auto" /></a></p>
<p>Fortunately, the discussion about the problem on the Vite repository led me to discover a solution.</p>
<h3 id="heading-solution-2">Solution</h3>
<p>Before I mention the solution, here's the issue raised for the error on the Vite repository: <a target="_blank" href="https://github.com/vitejs/vite/issues/2139">Encountered “Minified React error” in the production environment</a></p>
<p>It has 71 participants contributing to the discussion and still the issue isn't closed, so it seems there are still some libraries that may cause the error.</p>
<p>The solution to this problem was to check if the imported component has the property <code>default</code> if it has the property <code>default</code>, then the default component should be used otherwise the component should be used.</p>
<p>Here's a snippet to check for default components in the <code>react-phone-input-2</code> library and the solution to my problem.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> RPI <span class="hljs-keyword">from</span> <span class="hljs-string">"react-phone-input-2"</span>; 

<span class="hljs-keyword">const</span> ReactPhoneInput = RPI.default ? RPI.default : RPI;
</code></pre>
<p>Thanks to <a target="_blank" href="https://github.com/Kylar13">Kylar13</a> for his comment, I was able to detect that it was the <code>react-phone-input-2</code> library that was giving me the error, but then from the issue discussions, I could have other libraries installed that could have the same problem.</p>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1133130323"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678279616052/72ea048d-753d-423c-ac5a-afe9866b3dac.png" alt class="image--center mx-auto" /></a></p>
<p>So I needed a permanent fix, luckily after going through the 80+ comments on the issue I found a permanent fix posted by <a target="_blank" href="https://github.com/Boni0">Boni0</a>.</p>
<p>Here's the full discussion by Boni0: <a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1399098579">https://github.com/vitejs/vite/issues/2139#issuecomment-1399098579</a></p>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1399098579"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678280270865/84d04281-b70a-4f0e-8f94-b20e542bb57d.png" alt class="image--center mx-auto" /></a></p>
<p>But here's the solution I ended up using in my codebase, which works fine now.</p>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/2139#issuecomment-1405624744"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678280450807/0233c2b8-385f-4710-87be-726a5b4f66dd.png" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-4-uncaught-referenceerror-makestylesdefault-is-not-defined">4. Uncaught ReferenceError: makeStyles_default is not defined</h3>
<p>This is one of that errors that can make one cry and regret migrating to Vite 😅. Why do I say this? (<em>assume you heard me ask the question 😄</em>) Because the error is unpredictable and comes and goes while blocking you from doing anything in development. Also, the error comes in different forms, it could be <code>Uncaught ReferenceError: Box_default is not defined</code>.</p>
<p>I guess the issue is with MUI, not working properly with ESM or something like that, though I found a solution that works, I can't say the root of the problem.</p>
<h3 id="heading-solution-3">Solution</h3>
<p>Remember I mentioned the error is unpredictable, so take this solution with a grain of salt, cause I don't know why the issue comes up.</p>
<p>From the issue - <a target="_blank" href="https://github.com/vitejs/vite/issues/1853">Exported variable in chunk is not defined · Issue #1853</a>, I found out it's better to use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#named_import">named import</a> while importing components from MUI.</p>
<p>So use this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Box } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mui/material'</span>;
</code></pre>
<p>Instead of:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Box <span class="hljs-keyword">from</span> <span class="hljs-string">'@mui/material/Box'</span>;
</code></pre>
<p>Also, from the issue, it was mentioned to add <code>esm</code> as the suffix to the package MUI.</p>
<p><a target="_blank" href="https://github.com/vitejs/vite/issues/1853#issuecomment-793026832"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678284575117/3bbf10ad-34b9-4aa5-90e5-b9fc118747f1.png" alt class="image--center mx-auto" /></a></p>
<p>So I did this on my end, in the <code>vite.config.js</code> file:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678285108690/25e73dff-9b5e-43b1-a3ae-e326780d00f2.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-5-uncaught-typeerror-styleddefault-is-not-a-function">5. Uncaught TypeError: styled_default is not a function</h3>
<p>This error is also one that's unpredictable and is caused by MUI. I've encountered this error more than once, and I haven't found a permanent fix for it, I just hope I wouldn't see it again.</p>
<p>The error doesn't allow me to make changes on development, so all I saw on the browser is a blank white screen, hence I had to fix it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678285227445/52000ce9-d03b-40f5-960d-0a0014f062c4.png" alt class="image--center mx-auto" /></p>
<p>At the point of writing this article, I still got this error and here's a comment I made on the issue - ﻿ <a target="_blank" href="https://github.com/mui/material-ui/issues/32727">Popper.js:9 Uncaught TypeError: styled_default is not a function</a></p>
<p><a target="_blank" href="https://github.com/mui/material-ui/issues/32727#issuecomment-1447936047"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678285829860/1be4618f-b1e1-46cd-ba72-06dde7f41ab2.png" alt class="image--center mx-auto" /></a></p>
<h3 id="heading-proposed-solution">Proposed Solution</h3>
<p>From the issue mentioned above, the solution which works most time is to delete the <code>node_modules</code> folder and reinstall all your dependencies.</p>
<p>Another solution that worked for someone is to use <code>@vitejs/plugin-react-swc</code> instead of <code>@vitejs/plugin-react</code>.</p>
<p>I have tried all the proposed solutions on the issue - <a target="_blank" href="https://github.com/mui/material-ui/issues/32727">Popper.js:9 Uncaught TypeError: styled_default is not a function</a>, must times it works, while sometimes it doesn't. I'll leave it at that, though currently, I don't get the error.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Do I regret migrating from Create-React-App to Vite? No, maybe a little, Yes, cause I have to go through lots of issues to figure things out.</p>
<p>Was there an improvement in server startup time, installing dependencies, and production build? Yessss, Vite is so fast. Blazingly fast ❤️‍🔥.</p>
<hr />
<p>So I cloned the legacy codebase, the one using Create-React-App, installed the dependencies and started the server. It took <strong>5 min, and 34 sec</strong> for the server to startup and reflect on the browser 😫.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678290350144/ad5534ba-866d-463a-bd09-824184ffc607.png" alt class="image--center mx-auto" /></p>
<p>The above test was done when I was starting the server for the first time, the second time I started the server, it took <strong>1 min and 33 secs</strong> which is fairly okay I guess. But Vite took <strong>35 secs</strong> for the browser to show the webpage fully loaded though it wasn't the first time I had started the server.</p>
<hr />
<p>Would I ever use MUI for any reason in the future? Definitely, NO. If not that it would be a tug of war to remove MUI from my work codebase, I would have removed it.</p>
<p>With all of this, I leave with this, if you're migrating from CRA to Vite, and you're using MUI in your codebase, just know you're in for soup 🤣.</p>
<p>If you found this article helpful in a way, do like, sh, are, and follow me for more articles. Also, if you have a simpler approach or solution to solve the issues I mentioned in the article, please drop them in the comment, I'll love to see them.</p>
<p>I'll make sure to keep this article updated if I encounter more errors or bugs due to the migration.</p>
<p><strong>Thanks for reading!</strong></p>
]]></content:encoded></item><item><title><![CDATA[4 Features in VSCode I use to speed up my Workflow]]></title><description><![CDATA[Visual Studio Code (VS Code) is my favourite code editor, even though I haven't tried all the possible code editors out there, I can say VS Code is my best 😊. In this article, we'll go over 4 features this great editor has, which make it just right,...]]></description><link>https://blog.favouritejome.dev/4-features-in-vscode-i-use-to-speed-up-my-workflow</link><guid isPermaLink="true">https://blog.favouritejome.dev/4-features-in-vscode-i-use-to-speed-up-my-workflow</guid><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[vscode]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sat, 18 Feb 2023 05:32:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676698258035/5ca5a77e-b480-49d3-a1a7-6771a0648511.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Visual Studio Code (VS Code) is my favourite code editor, even though I haven't tried all the possible code editors out there, I can say VS Code is my best 😊. In this article, we'll go over 4 features this great editor has, which make it just right, to speed up productivity and a lifesaver at best.</p>
<h2 id="heading-1-searching-capabilities">1. Searching Capabilities</h2>
<p>The search feature is just amazing in VS Code and there are several modes of searching too, we could search for files, symbols (which means variable names, function names and so on), references, etc. but let's go over the 3 search features I mostly make use of.</p>
<h3 id="heading-1a-command-palette-ctrlshiftp">1a) Command Palette (Ctrl+Shift+P)</h3>
<p>The Command Palette allows you to have all the functionalities of VS Code in one place. Functionalities such as all GIT commands (like push, pull, etc.), reloading the window, and so on can be accessed from the command palette, but that's not all.</p>
<p>The command palette gives room for many commands, but let's go over just one, which allows us to navigate the various files in the codebase, by their file names or symbols. To work with the navigating feature, the command is <strong>Ctrl + P</strong>.</p>
<p>And when the command <strong>Ctrl + P</strong> is typed, the interface appears like the image below, and of course, shows your files in your codebase, allowing you to jump through files quickly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676547997772/9b916ca3-bfdd-49d8-9a02-7e37cea3f54f.png" alt class="image--center mx-auto" /></p>
<p>Bonus trick, you could press the command <strong>Ctrl + P</strong> multiple times, to navigate down through the files showing on the command palette. In the case of the image above, if <strong>Ctrl + P</strong> is typed again, the file <strong>ChartTiles.jsx</strong> will be selected. Then to up the files, you can make use of <strong>Ctrl + Shift + P</strong> provided, you were on the navigating palette.</p>
<blockquote>
<p>To view all other amazing commands you have access to using the command palette, please visit <a target="_blank" href="https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette">Visual Studio Code User Interface</a></p>
</blockquote>
<h3 id="heading-1b-search-on-activity-bar-ctrl-shift-f">1b) Search on Activity Bar (Ctrl + Shift + F)</h3>
<p>The Search on the Activity Bar is pretty powerful, as well, it allows you to search and replace words across the codebase. So if you're looking for every occurrence of some symbol or string for example <em>"@mui/material"</em> in the codebase, you could just search for it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676549770929/93027328-d0ef-4088-a662-0ca73b1f3484.png" alt class="image--center mx-auto" /></p>
<p>This search feature is even more powerful especially when you want to find something really specific, like every occurrence of the symbol or variable name for example <code>getNames</code>.</p>
<p>From the image below, you can see the word <strong>GETNAME</strong> is searched and it's capitalised, yet the result isn't case-sensitive.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676550331653/953d546e-85d5-41be-ba1c-db0471123a73.png" alt class="image--center mx-auto" /></p>
<p>To make it case-sensitive or in any other case, search accurately to what is actually being searched for, that's where the three options provided come into play, which are <strong>Match Case (Alt + C), Match Whole Word (Alt + W), Use Regular Expression (Alt + R)</strong>.</p>
<p>From the example above, we care about the case, so we can select <strong>Match Case (Alt + C)</strong> to be precise.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676550655518/48dd1572-83ba-4a5d-9405-33ab5ad24940.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>If by chance, you don't what's the Activity Bar, please visit here: <a target="_blank" href="https://code.visualstudio.com/api/ux-guidelines/activity-bar">Activity Bar | Visual Studio Code Extension API</a></p>
</blockquote>
<h3 id="heading-1c-search-by-reference-shift-f12">1c) Search by Reference (Shift + F12)</h3>
<p>The search by reference or as named in VS Code, <strong>Go to Reference</strong> comes in handy when you want to quickly just see all occurrences of symbols or words across your codebase or the current file opened.</p>
<p>For example, let's say you've made use of the <code>useState</code> hook from React, in multiple places in a file and you, want to jump over to every reference of the hook in your file. While the hook, <code>useState</code> is selected, you could either right-click on the word and select <strong>Go to Reference</strong> or use the shortcut <strong>Shift + F12</strong>. Doing so you get something similar to the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676553993447/7a912ad3-d421-4b20-8795-4064c8d6800d.png" alt class="image--center mx-auto" /></p>
<p>The file currently opened is named <code>IncomeModal.jsx</code> so that is why it shows on the left-hand side of the pop-up, but take note of the other file there, the <code>index.d.ts</code> file which is in the <code>node_modules</code> directory. The <code>index.d.ts</code> file shows because the <code>useState</code> hook is coming from the definition in the <code>index.d.ts</code> file.</p>
<blockquote>
<p>Quick note, in my use case, I don't care about the <code>index.d.ts</code> file and I don't know how it really works😅 but I think there's a reference to the <code>index.d.ts</code> file. All I care about is jumping around where I have the <code>useState</code> hook in my current file.</p>
</blockquote>
<p>Now, there's another cool feature with the Search by Reference worth mentioning that brings the power of reference. Let's go over another use case.</p>
<p>For example, let's say you've made a custom hook in React or you're using some library that has its custom hook and you want to search for every reference to the custom hook. Then again, using the shortcut <strong>Shift + F12</strong> you can see every reference of the hook and in most cases, if used in multiple files you'll see that too.</p>
<p>From the image, below, I made a search by reference for the <code>useTranslation</code> hook, and it's being referenced in <strong>213</strong> files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676555038582/14235cc0-5f7e-4899-8ae3-7ace6504ac99.png" alt class="image--center mx-auto" /></p>
<p>The Search by Reference feature is kinda similar to the Search on the Activity bar, but then they are very different, so you can choose which to use.</p>
<h2 id="heading-2-rename-symbols-f2httpscodevisualstudiocomdocseditoreditingevolvedrename-symbol">2. <a target="_blank" href="https://code.visualstudio.com/docs/editor/editingevolved#_rename-symbol">Rename Symbols (F2)</a></h2>
<p>Rename Symbols is just mind-blowing 🤯 (I might be overemphasising but it's a cool feature). This feature allows you to rename a symbol (again which could be a file name, function name, variable name, etc) across multiple files. So you can rename a variable name and be certain that all references to that variable name will be changed as well.</p>
<p>For example, on a file, let's rename the state name of the <code>useState</code> hook to something else. In the image below, I'm renaming the state <code>revenueDate</code> to <code>revenueDatee</code>, now everywhere where <code>revenueDate</code> was used will be changed to <code>revenueDatee</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676557539889/4dec1f6d-8940-4b23-92f8-3d62f222d178.png" alt class="image--center mx-auto" /></p>
<p>Quick note, to see all the occurrences of the state changing, type <strong>Shift + Enter</strong>, which opens the Refactor Preview and shows what would be removed and replaced. If you're happy with it, click Apply else Discard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676557908659/98d24fa8-6636-43e9-bd9d-a383ea7dce62.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-3-source-control-with-git-ctrl-shift-ghttpscodevisualstudiocomdocssourcecontroloverview">3. <a target="_blank" href="https://code.visualstudio.com/docs/sourcecontrol/overview">Source Control with Git (Ctrl + Shift + G)</a></h2>
<p>The Souce Control in VS Code allows the ease of just clicking on some buttons and all your GIT operations will be done for you without writing a single command. The Souce Control view can be accessed on the Activity bar, or with the shortcut <strong>Ctrl + Shift + G</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676674590849/b3f726a2-17e7-4c18-992d-6439de486953.png" alt class="image--center mx-auto" /></p>
<p>I wrote an article about source control in VS Code: <a target="_blank" href="https://favouritejome.hashnode.dev/vs-code-version-control-understanding-the-basics-of-git-operations-1"><strong>VS Code Version Control: Understanding the basics of Git operations # 1</strong></a><strong>,</strong> you can read it to know how it works.</p>
<p>Also, please the VS Code docs are extremely helpful, here's all the <a target="_blank" href="https://code.visualstudio.com/docs/sourcecontrol/overview">Source Control with Git in Visual Studio Code</a>.</p>
<h2 id="heading-4-multiple-selectionshttpscodevisualstudiocomdocseditorcodebasicsmultiple-selections-multicursor-multi-cursorhttpscodevisualstudiocomdocseditorcodebasicsmultiple-selections-multicursor">4. <a target="_blank" href="https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor">Multiple selections</a> <a target="_blank" href="https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor">(multi-cursor)</a></h2>
<p>Multiple selection is a feature that allows you to place your cursor in multiple locations on a file, and then give room for editing where the cursor has been placed. The most common way of using this feature is when you have similar text all around a file, and you'll like to change the text to something else.</p>
<p>Looking at the image below, you'll see the text <strong>200</strong> is changed to <strong>120</strong> at the same time.</p>
<p><img src="https://code.visualstudio.com/assets/docs/editor/codebasics/multicursor.gif" alt="Multi-cursor" /></p>
<blockquote>
<p><em>The above image is from</em> <a target="_blank" href="https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor">VS Code docs</a></p>
</blockquote>
<p>There are different commands in VS Code that'll aid you to make sure of the Multiple selection feature, but the most common command, at least the one I use often is <strong>Ctrl + D</strong>, which selects the next occurrence of some text or symbol selected, and adds multiple cursors.</p>
<p>There are other commands that could multi-select in a different scenario, mostly when the texts aren't similar, but please go through the <a target="_blank" href="https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor">docs</a> to find out more.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>There are several other features in VS Code not covered in this article and it will be an endless article if we were to go over all of them. So, I'll advise you to go through <a target="_blank" href="https://code.visualstudio.com/docs">VS Code documentation</a> more frequently or at least subscribe to their <a target="_blank" href="https://www.youtube.com/@code">YouTube Channel</a>, their shorts are very helpful.</p>
<p>Hopefully, you've learnt a new feature in VS Code, and if you already make use of all these features, you're a PRO 😅. By the way, if you know of any feature that helps you a lot while coding, please drop it in the comments.</p>
<p>Thanks for reading and see you in the next article!</p>
]]></content:encoded></item><item><title><![CDATA[Let's build a Calculator App (React Native)]]></title><description><![CDATA[Welcome back to the Let's build Something Cool series, where we build cool things, at least from my perspective 😊, but really it's a series where we go in-depth about the cool things I build, but then we get to build it together.
In this article, we...]]></description><link>https://blog.favouritejome.dev/lets-build-a-calculator-app-react-native</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-a-calculator-app-react-native</guid><category><![CDATA[calculator]]></category><category><![CDATA[React Native]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Thu, 19 Jan 2023 00:42:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674088659651/a915469f-8fd4-40a5-92c9-3f1f1ffc45d4.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back to the <a target="_blank" href="https://favouritejome.hashnode.dev/series/lets-build-something-cool">Let's build Something Cool</a> series, where we build cool things, at least from my perspective 😊, but really it's a series where we go in-depth about the cool things I build, but then we get to build it together.</p>
<p>In this article, we'll build a Calculator application similar to Samsung's calculator app, and use <a target="_blank" href="https://expo.dev/">Expo</a>, a framework that allows us to get started with React Native applications quickly.</p>
<blockquote>
<p>There are a bunch of requirements we'll need before building in the Calculator application, but if you'll like to skip the requirements section cause you're familiar with React Native and Expo, <a class="post-section-overview" href="#heading-getting-started">click here to do so</a>.</p>
</blockquote>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li><p>Basic knowledge of React</p>
</li>
<li><p>Basic knowledge of React Native</p>
</li>
</ul>
<h2 id="heading-requirements">Requirements</h2>
<h3 id="heading-install-node">Install Node</h3>
<p>Node is pretty much essential, so visit <a target="_blank" href="https://nodejs.org/en/">Nodejs.org</a> and download the Long Term Support (LTS) version of Nodejs.</p>
<p>Once you're done downloading and installing Node.js, run the command below to know if it's up and running on your machine.</p>
<pre><code class="lang-bash">node -v
</code></pre>
<h3 id="heading-install-expo"><strong>Install Expo</strong></h3>
<p>There are two tools we'll need to set up Expo, first is the <a target="_blank" href="https://docs.expo.dev/get-started/installation/#expo-cli">Expo CLI</a> which serves the project, and second is the client app called <a target="_blank" href="https://docs.expo.dev/get-started/installation/#expo-go-app-for-android-and-ios">Expo GO</a> which allows us to view the project on either an Andriod or IOS device.</p>
<p><strong>Install Expo CLI</strong></p>
<pre><code class="lang-bash">npm install -g expo-cli
</code></pre>
<p><strong>Install Expo Go</strong></p>
<ul>
<li><p><a target="_blank" href="https://play.google.com/store/apps/details?id=host.exp.exponent">Android Play Store</a></p>
</li>
<li><p><a target="_blank" href="https://apps.apple.com/app/expo-go/id982107779">iOS App Store</a></p>
</li>
</ul>
<blockquote>
<p>Further guides for the <a target="_blank" href="https://docs.expo.dev/get-started/installation/">Expo installation can be found here.</a></p>
</blockquote>
<h2 id="heading-getting-started">Getting Started</h2>
<p>Firstly we'll need to install the necessary dependencies to get building, and the first would be Expo.</p>
<pre><code class="lang-bash">npx create-expo-app calculator-app &amp;&amp; <span class="hljs-built_in">cd</span> calculator-app
</code></pre>
<p>Once the installation process is completed and we've changed our directory to <code>calculator-app</code>, let's start our app, making sure it works.</p>
<h3 id="heading-run-the-project">Run the Project</h3>
<pre><code class="lang-bash">npm start
</code></pre>
<p><code>yarn start</code> would also work if you have yarn installed.</p>
<p>On the terminal, you'll see a QR code, which we'll need to scan with the <a target="_blank" href="https://play.google.com/store/apps/details?id=host.exp.exponent">Expo Go app</a>, which I guess you've downloaded from Play Store already.</p>
<blockquote>
<p>But if you've not got the Expo app yet, <a target="_blank" href="https://play.google.com/store/apps/details?id=host.exp.exponent">download it here for Android</a> and here for <a target="_blank" href="https://apps.apple.com/app/expo-go/id982107779">iOS</a> to follow along with the article.</p>
</blockquote>
<p>To work with the Expo Go app and our project on our computers, we would need to be connected to the same network; this is very important.</p>
<p>The terminal interface should look like this when the <code>start</code> command is run:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673733081635/309e00d2-e30b-4de9-a295-4e27bd011a1a.png" alt="npm start" class="image--center mx-auto" /></p>
<p>Now, we need to open the Expo Go app on our mobile devices, scan the QR code, and we should see this interface on our phones.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674087239751/97c23339-e773-437c-86ac-c4d11bab48fc.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-folder-structure">Folder Structure</h3>
<p>Let's go over what the folder structure entails:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673733844349/edc19858-73a1-411b-a886-5fe7e0b29364.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>Note: As of the Expo version <code>47.0.12</code>, this is how the folder structure is</p>
</blockquote>
<ul>
<li><p>/.expo - this folder got created when we started the application and contains devices.json and README.md files. Please go through the README file to know what this folder is about, but really we can ignore it.</p>
</li>
<li><p>/assets - this is where we store any assets we may want to use in our application, like images, videos, fonts and icons</p>
</li>
<li><p>/node_modules - these are all the packages we have installed that allow Expo and React Native to run. Further packages installed with <code>npm install</code> get added here.</p>
</li>
<li><p>.gitignore - this is a file to tell .git which files and directories we want to omit from source control (Git). node_modules and .expo directories are omitted by default.</p>
</li>
<li><p>App.js - the main entry point to our application. This is where you'll start adding code!</p>
</li>
<li><p>app.json - another config file that contains expo metadata</p>
</li>
<li><p>babel.config.js - babel config, used to add the expo preset</p>
</li>
<li><p>package.json - this is where you list dependencies and add scripts</p>
</li>
<li><p>package-lock.json - this file shows the map of all the dependencies installed</p>
</li>
</ul>
<h3 id="heading-breakdown-of-the-calculator-layout">Breakdown of the Calculator Layout</h3>
<p>The calculator app UI can be broken down into four main components we'll need to build; first, an input box where the calculations would be done, referred to as the <strong>Calculation Input</strong> from the image below.</p>
<p>Then we have the <strong>Preview Calculation</strong> component, which shows a preview of the answer when a valid operation occurs; next, we have <strong>Rows</strong> of <strong>Buttons</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673902164713/cc7afd54-8a44-48d5-9261-63511f101360.jpeg" alt="Samsung Calculator app" class="image--center mx-auto" /></p>
<blockquote>
<p><em>I'm sorry for the poor image quality, I'll look for better ways to edit images next time 😅</em></p>
</blockquote>
<h3 id="heading-coding-time">Coding Time</h3>
<p>Let's open the <code>App.js</code> file, we should have the snippet of code below or similar in the file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">'expo-status-bar'</span>;
<span class="hljs-keyword">import</span> { StyleSheet, Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>&gt;</span>Open up App.js to start working on your app!<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"auto"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'#fff'</span>,
    <span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
  },
});
</code></pre>
<p>We'll need to create the Calculation Input first, so remove the <code>&lt;Text&gt;</code> component and replace it with an <code>&lt;TextInput /&gt;</code> component.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">'expo-status-bar'</span>;
<span class="hljs-keyword">import</span> { StyleSheet, Text, View } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Here's were we type our calculation!"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"auto"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'#fff'</span>,
    <span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
  },
});
</code></pre>
<p>Here's what we should have on the Expo Go app on our devices.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673911341890/21c74f29-9f69-4c79-81c0-22a94b9b4cba.png" alt class="image--center mx-auto" /></p>
<p>Notice the input is at the centre of the screen; let's fix that and add some colours.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { StyleSheet, Text, TextInput, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.input}</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">"Here's were we type our calculation!"</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#010101"</span>,
    <span class="hljs-attr">paddingVertical</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">paddingHorizontal</span>: <span class="hljs-number">20</span>,
  },
  <span class="hljs-attr">input</span>: {
    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">40</span>,
    <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">padding</span>: <span class="hljs-number">10</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"#fff"</span>,
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">36</span>,
  },
});
</code></pre>
<p>Now the UI should look like this, which is much better.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673911915126/5991d2f6-d201-4c59-8751-ae4ce76d0cf4.png" alt class="image--center mx-auto" /></p>
<p>Let's add state to the <code>&lt;TextInput /&gt;</code> to keep track of the calculating number and operators entered.</p>
<pre><code class="lang-javascript">...
export <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.input}</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{calValue}</span>
        <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setCalValue}</span>
        <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
        <span class="hljs-attr">autoFocus</span>=<span class="hljs-string">{true}</span>
        <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
        <span class="hljs-attr">showSoftInputOnFocus</span>=<span class="hljs-string">{false}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}
...
</code></pre>
<p>The Calculation Input is all set, but notice the <code>showSoftInputOnFocus={false}</code> prop on the <code>&lt;TextInput /&gt;</code> component. The prop is added to make sure the phone keyboard doesn't show when the input is on focus cause we don't need the phone's keyboard; we'll create ours.</p>
<p>Let's move to the Preview Calculation Input, which follows the same pattern we did for the calculation input.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { StyleSheet, Text, TextInput, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [previewValue, setPreviewValue] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.input}</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{calValue}</span>
        <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setCalValue}</span>
        <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
        <span class="hljs-attr">autoFocus</span>=<span class="hljs-string">{true}</span>
        <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
        <span class="hljs-attr">showSoftInputOnFocus</span>=<span class="hljs-string">{false}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{previewValue}</span>
        <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setPreviewValue}</span>
        <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
        <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
        <span class="hljs-attr">caretHidden</span>=<span class="hljs-string">{true}</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.input,</span> <span class="hljs-attr">styles.prevInput</span>]}
        <span class="hljs-attr">showSoftInputOnFocus</span>=<span class="hljs-string">{false}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#010101"</span>,
    <span class="hljs-attr">paddingVertical</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">paddingHorizontal</span>: <span class="hljs-number">20</span>,
  },
  <span class="hljs-attr">input</span>: {
    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">40</span>,
    <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">padding</span>: <span class="hljs-number">10</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"#fff"</span>,
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">36</span>,
  },
  <span class="hljs-attr">prevInput</span>: {
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">24</span>,
    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">40</span>,
    <span class="hljs-attr">marginBottom</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"#616161"</span>,
  },
});
</code></pre>
<p>Next, let's move the backspace button; for this, we'll need to install a package <code>@expo/vector-icons</code> which comes with the icon we need. Run the command below:</p>
<pre><code class="lang-bash">npm install @expo/vector-icons
</code></pre>
<p>Once it's installed, we'll need to add the backspace icon to the code and its functionality.</p>
<pre><code class="lang-javascript">...
import { Pressable, StyleSheet, Text, TextInput, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [previewValue, setPreviewValue] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> handleBackSpace = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> remainValue = calValue.slice(<span class="hljs-number">0</span>, calValue.length - <span class="hljs-number">1</span>);
    setCalValue(<span class="hljs-function">() =&gt;</span> remainValue);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.input}</span> <span class="hljs-attr">...</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{previewValue}</span> <span class="hljs-attr">...</span>
      /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.backButton}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Pressable</span>
          <span class="hljs-attr">onPress</span>=<span class="hljs-string">{()</span> =&gt;</span> handleBackSpace()}
          disabled={calValue ? false : true}
        &gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Ionicons</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">'md-backspace-outline'</span>
            <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span>
            <span class="hljs-attr">color</span>=<span class="hljs-string">{calValue</span> ? "<span class="hljs-attr">green</span>" <span class="hljs-attr">:</span> "#<span class="hljs-attr">035903</span>"}
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Pressable</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">View</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
          <span class="hljs-attr">height:</span> <span class="hljs-attr">1</span>,
          <span class="hljs-attr">backgroundColor:</span> "#<span class="hljs-attr">575757</span>",
          <span class="hljs-attr">marginVertical:</span> <span class="hljs-attr">20</span>,
        }}
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StatusBar</span> <span class="hljs-attr">style</span>=<span class="hljs-string">'auto'</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {...},
  <span class="hljs-attr">input</span>: {...},
  <span class="hljs-attr">prevInput</span>: {...},
  <span class="hljs-attr">backButton</span>: {
    <span class="hljs-attr">flexDirection</span>: <span class="hljs-string">"row"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"flex-end"</span>,
  },
});
</code></pre>
<p>Notice from the snippet above the <code>Pressable</code> component is used to indicate the icon would be clicked and has two props, <code>onPress</code> which listens to the pressing of the icon, which then calls the <code>handleBackSpace</code> function, and the second prop is <code>disabled</code> , which makes the icons not pressable when there's no value in the Calculation input.</p>
<p>The <code>handleBackSpace()</code> function removes the last value in the <code>calValue</code> state and then update the <code>calValue</code> state.</p>
<p>The self-closing <code>View</code> component is to indicate a line in the UI. Now the UI should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673918515288/77020d50-613a-4263-8966-ae7d887e874d.png" alt class="image--center mx-auto" /></p>
<p>From the UI, we know we need a row of buttons, so let's create a component named <code>Row</code> but still, in this <code>App.js</code> file cause, it isn't a complicated component.</p>
<pre><code class="lang-javascript">...
export <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
...
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Row</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.row}</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>;
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  ...
  row: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">flexDirection</span>: <span class="hljs-string">"row"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"space-between"</span>,
  },
});
</code></pre>
<p>That's all for the <code>Row</code> component; it basically composes several button components, which we'll be working on next.</p>
<p>Let's create a new component named <code>Button.js</code> in a components directory from the root directory, that is:</p>
<pre><code class="lang-bash">|-components
| -- Button.js
App.js
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// Button.js</span>

<span class="hljs-keyword">import</span> { TouchableHighlight, Text, StyleSheet } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</span>(<span class="hljs-params">{ label, type, handlePress, icon }</span>) </span>{
  <span class="hljs-keyword">const</span> getTextColor =
    type === <span class="hljs-string">"operator"</span> ? <span class="hljs-string">"green"</span> : type === <span class="hljs-string">"clear"</span> ? <span class="hljs-string">"red"</span> : <span class="hljs-string">"#fff"</span>;

  <span class="hljs-keyword">const</span> getButtonColor =
    type === <span class="hljs-string">"equal"</span>
      ? { <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"green"</span> }
      : { <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#171717"</span> };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TouchableHighlight</span>
      <span class="hljs-attr">underlayColor</span>=<span class="hljs-string">{type</span> === <span class="hljs-string">"equal"</span> ? "#<span class="hljs-attr">04ac04</span>" <span class="hljs-attr">:</span> "#<span class="hljs-attr">444444</span>"}
      <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.button,</span> <span class="hljs-attr">getButtonColor</span>]}
      <span class="hljs-attr">onPress</span>=<span class="hljs-string">{()</span> =&gt;</span> handlePress(label)}
    &gt;
      {icon ? (
        icon
      ) : (
        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">fontSize:</span> <span class="hljs-attr">26</span>, <span class="hljs-attr">color:</span> <span class="hljs-attr">getTextColor</span>, <span class="hljs-attr">fontWeight:</span> "<span class="hljs-attr">bold</span>" }}&gt;</span>
          {label}
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">TouchableHighlight</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">button</span>: {
    <span class="hljs-attr">borderRadius</span>: <span class="hljs-number">50</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#171717"</span>,
    <span class="hljs-attr">width</span>: <span class="hljs-number">80</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">80</span>,
    <span class="hljs-attr">alignItems</span>: <span class="hljs-string">"center"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"center"</span>,
  },
});
</code></pre>
<p>From the code above, we can see there's a lot going on. The Button component accepts four pros <code>{ label, type, handlePress, icon }</code> where</p>
<ul>
<li><p><code>Label</code> is the text or number that the button should display</p>
</li>
<li><p><code>type</code> prop is to identify what the button does; is it going to be for an <strong>operator</strong> or <strong>clear</strong> (which removes the numbers and operator for the Calculation Input) or <strong>number</strong>.</p>
</li>
<li><p><code>handlePress</code> prop is a function that takes in the <code>label</code> as an argument and does the necessary operation with it, which we'll get into later on.</p>
</li>
<li><p><code>icon</code> prop is an icon component that will be displayed in the button instead of the <code>label</code> if available.</p>
</li>
</ul>
<p>Now, let's add the button components to the `App.js` file and their various functionalities.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { StatusBar } <span class="hljs-keyword">from</span> <span class="hljs-string">"expo-status-bar"</span>;
<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Pressable, StyleSheet, Text, TextInput, View } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-native"</span>;
<span class="hljs-keyword">import</span> { Ionicons, FontAwesome5, FontAwesome } <span class="hljs-keyword">from</span> <span class="hljs-string">"@expo/vector-icons"</span>;
<span class="hljs-keyword">import</span> { MaterialCommunityIcons } <span class="hljs-keyword">from</span> <span class="hljs-string">"@expo/vector-icons"</span>;
<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/Button"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [previewValue, setPreviewValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [isAnswer, setIsAnswer] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> ansColor = {
    <span class="hljs-attr">color</span>: isAnswer ? <span class="hljs-string">"green"</span> : <span class="hljs-string">"white"</span>,
  };

  <span class="hljs-keyword">const</span> handleBackSpace = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> remainValue = calValue.slice(<span class="hljs-number">0</span>, calValue.length - <span class="hljs-number">1</span>);
    setCalValue(<span class="hljs-function">() =&gt;</span> remainValue);
  };

  <span class="hljs-keyword">const</span> handlePress = <span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</span> {
    setIsAnswer(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> corrText = text === <span class="hljs-string">"X"</span> ? <span class="hljs-string">"*"</span> : text === <span class="hljs-string">"+/-"</span> ? <span class="hljs-string">"-"</span> : text;
    setCalValue(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> prev + <span class="hljs-string">`<span class="hljs-subst">${corrText}</span>`</span>);
  };

  <span class="hljs-keyword">const</span> handleClear = <span class="hljs-function">() =&gt;</span> {
    setCalValue(<span class="hljs-string">""</span>);
  };

  <span class="hljs-keyword">const</span> handleEqual = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!previewValue) <span class="hljs-keyword">return</span>;
    setCalValue(previewValue);
    setPreviewValue(<span class="hljs-string">""</span>);
    setIsAnswer(<span class="hljs-literal">true</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.input,</span> <span class="hljs-attr">ansColor</span>]}
        <span class="hljs-attr">value</span>=<span class="hljs-string">{calValue}</span>
        <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setCalValue}</span>
        <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
        <span class="hljs-attr">autoFocus</span>=<span class="hljs-string">{true}</span>
        <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
        <span class="hljs-attr">showSoftInputOnFocus</span>=<span class="hljs-string">{false}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{previewValue}</span>
        <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setPreviewValue}</span>
        <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
        <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
        <span class="hljs-attr">caretHidden</span>=<span class="hljs-string">{true}</span>
        <span class="hljs-attr">showSoftInputOnFocus</span>=<span class="hljs-string">{false}</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.input,</span> <span class="hljs-attr">styles.prevInput</span>]}
      /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.backButton}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Pressable</span>
          <span class="hljs-attr">onPress</span>=<span class="hljs-string">{()</span> =&gt;</span> handleBackSpace()}
          disabled={calValue ? false : true}
        &gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Ionicons</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">'md-backspace-outline'</span>
            <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span>
            <span class="hljs-attr">color</span>=<span class="hljs-string">{calValue</span> ? "<span class="hljs-attr">green</span>" <span class="hljs-attr">:</span> "#<span class="hljs-attr">035903</span>"}
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Pressable</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">View</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
          <span class="hljs-attr">height:</span> <span class="hljs-attr">2</span>,
          <span class="hljs-attr">backgroundColor:</span> "#<span class="hljs-attr">575757</span>",
          <span class="hljs-attr">marginVertical:</span> <span class="hljs-attr">20</span>,
        }}
      /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.buttonContainer}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handleClear}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">C</span>"} <span class="hljs-attr">type</span>=<span class="hljs-string">'clear'</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"()"}
            <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span>
            <span class="hljs-attr">icon</span>=<span class="hljs-string">{</span>
              &lt;<span class="hljs-attr">MaterialCommunityIcons</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'code-parentheses'</span>
                <span class="hljs-attr">size</span>=<span class="hljs-string">{30}</span>
                <span class="hljs-attr">color</span>=<span class="hljs-string">'green'</span>
                <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">fontWeight:</span> "<span class="hljs-attr">bold</span>" }}
              /&gt;</span>
            }
          /&gt;
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"%"} <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"/"}
            <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span>
            <span class="hljs-attr">icon</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">FontAwesome5</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'divide'</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span> <span class="hljs-attr">color</span>=<span class="hljs-string">'green'</span> /&gt;</span>}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">7</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">8</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">9</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">X</span>"}
            <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span>
            <span class="hljs-attr">icon</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">FontAwesome5</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'times'</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span> <span class="hljs-attr">color</span>=<span class="hljs-string">'green'</span> /&gt;</span>}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">4</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">5</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">6</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">-</span>"}
            <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span>
            <span class="hljs-attr">icon</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">FontAwesome</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'minus'</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span> <span class="hljs-attr">color</span>=<span class="hljs-string">'green'</span> /&gt;</span>}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">1</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">2</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">3</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"+"}
            <span class="hljs-attr">type</span>=<span class="hljs-string">'operator'</span>
            <span class="hljs-attr">icon</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">FontAwesome5</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'plus'</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{24}</span> <span class="hljs-attr">color</span>=<span class="hljs-string">'green'</span> /&gt;</span>}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"+/<span class="hljs-attr">-</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">0</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handlePress}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">.</span>"} /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
            <span class="hljs-attr">handlePress</span>=<span class="hljs-string">{handleEqual}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{</span>"=<span class="hljs-string">"}
            type='equal'
            icon={&lt;FontAwesome5 name='equals' size={24} color='white' /&gt;}
          /&gt;
        &lt;/Row&gt;
      &lt;/View&gt;

      &lt;StatusBar style='auto' /&gt;
    &lt;/View&gt;</span></span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Row</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag"><span class="hljs-string">&lt;View style={styles.row}&gt;{children}&lt;/View&gt;</span></span></span>;
}

<span class="hljs-keyword">const</span> styles = StyleSheet.create({
  <span class="hljs-attr">container</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#010101"</span>,
    <span class="hljs-attr">paddingVertical</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">paddingHorizontal</span>: <span class="hljs-number">20</span>,
  },
  <span class="hljs-attr">input</span>: {
    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">40</span>,
    <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">padding</span>: <span class="hljs-number">10</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"#fff"</span>,
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">36</span>,
  },
  <span class="hljs-attr">prevInput</span>: {
    <span class="hljs-attr">fontSize</span>: <span class="hljs-number">24</span>,
    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">40</span>,
    <span class="hljs-attr">marginBottom</span>: <span class="hljs-number">30</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"#616161"</span>,
  },
  <span class="hljs-attr">backButton</span>: {
    <span class="hljs-attr">flexDirection</span>: <span class="hljs-string">"row"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"flex-end"</span>,
  },
  <span class="hljs-attr">row</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">flexDirection</span>: <span class="hljs-string">"row"</span>,
    <span class="hljs-attr">justifyContent</span>: <span class="hljs-string">"space-between"</span>,
  },
  <span class="hljs-attr">buttonContainer</span>: {
    <span class="hljs-attr">flex</span>: <span class="hljs-number">4</span>,
  },
});
</code></pre>
<p>From the snippet above, we can tell a lot is going on, so I've created an Expo snack for this point of the application so that we can see and play around with the application at this point, just in case you haven't been coding along 😊.</p>
<iframe src="https://snack.expo.dev/embedded/@favouritejome/calculator-app-01?iframeId=zin9l29o0c&amp;preview=true&amp;platform=web&amp;theme=dark" height="100%" width="100%" style="display:block;overflow:hidden;background:#212121;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></iframe>

<blockquote>
<p>To get the best experience please switch to the Andriod / iOS tab below (depending on your device), and scan the QR code to test on your mobile device with the Expo Go app.</p>
</blockquote>
<p>The <code>Row</code> component composes of four <code>Button</code> components and each Button has a different or similar prop value. For example, the button for the equal operation, the prop <code>handlePress</code> uses the <code>handleEqual()</code> function, which sets the preview Calculation to the <strong>Calculation Input.</strong></p>
<p>The <code>handlePress()</code> function takes a text, and if the text is <code>X</code> it returns <code>*</code> and if <code>+\-</code> it returns <code>-</code> to the <code>corrText</code> variable, which then added to the previous value of the <code>calValue</code> state, also, the <code>setIsAnswer(false)</code> function is made false.</p>
<p>Notice also a new state is added <code>const [isAnswer, setIsAnswer] = useState(false)</code> , and it's to keep track of when the arithmetic calculation is correct and determine what colour the Calculation Input should be, either green or white, in the <code>ansColor</code> variable, which is added to the Calculation Input styles.</p>
<blockquote>
<p>Just to be clear , Calculation Input is referred to the very first <code>&lt;TextInput /&gt;</code> component, while Preview Input is the second <code>&lt;TextInput /&gt;</code>.</p>
</blockquote>
<p>Let's move to the preview input and make it work:</p>
<pre><code class="lang-javascript">...
import { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
...

function valueHasOp(text) {
  <span class="hljs-keyword">if</span> (text.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  <span class="hljs-keyword">if</span> (
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"+"</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"-"</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"*"</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"/"</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"%"</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">"("</span> ||
    text[text.length - <span class="hljs-number">1</span>] === <span class="hljs-string">")"</span>
  )
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt;= text.length; i++) {
    <span class="hljs-keyword">if</span> (
      text[i] === <span class="hljs-string">"+"</span> ||
      text[i] === <span class="hljs-string">"-"</span> ||
      text[i] === <span class="hljs-string">"*"</span> ||
      text[i] === <span class="hljs-string">"/"</span> ||
      text[i] === <span class="hljs-string">"%"</span>
    ) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [previewValue, setPreviewValue] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [isAnswer, setIsAnswer] = useState(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (valueHasOp(calValue)) {
      <span class="hljs-keyword">let</span> prevAns = <span class="hljs-built_in">eval</span>(calValue);
      setPreviewValue(<span class="hljs-string">`<span class="hljs-subst">${prevAns}</span>`</span>);
    } <span class="hljs-keyword">else</span> {
      setPreviewValue(<span class="hljs-string">``</span>);
    }
  }, [calValue]);

 ...

 return (
    ...
 )
}
</code></pre>
<iframe src="https://snack.expo.dev/embedded/@favouritejome/calculator-app-02?iframeId=ti91x2koh5&amp;preview=true&amp;platform=web&amp;theme=dark" height="100%" width="100%" style="display:block;overflow:hidden;background:#212121;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></iframe>

<p>From the snippet above, there's a <code>useEffect</code> hook, which checks for changes in the <code>calValue</code> state, and in its callback, there's a check with the <code>valueHasOp()</code> function, which checks if the string <code>calValue</code> has an operator, for example, if <code>calValue</code> is <code>2*2</code> the function returns <code>true</code>, if <code>calValue</code> is <code>2*</code> it returns <code>false</code> cause that isn't a valid operation, also if <code>calValue</code> is an empty string, it returns <code>false</code>.</p>
<p>If the <code>valueHasOp(calValue)</code> function returns <code>true</code> then this expression is executed <code>Function(`return ${calValue}`)()</code> which evaluate JavaScript expressions as strings. If you've seen the <code>eval()</code> method before, it is similar to the <code>Funtion()</code> method.</p>
<blockquote>
<p>If you'll like to learn more about the <code>Function</code> method, do read this guide: <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function - JavaScript | MDN (</a><a target="_blank" href="http://mozilla.org">mozilla.org</a><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">)</a> and also this article to know the difference between <code>eval()</code> and <code>Function()</code> : <a target="_blank" href="https://www.educative.io/answers/eval-vs-function-in-javascript">eval() vs. Function() in JavaScript (</a><a target="_blank" href="http://educative.io">educative.io</a><a target="_blank" href="https://www.educative.io/answers/eval-vs-function-in-javascript">)</a></p>
</blockquote>
<p>The returned value from the <code>Function(`return ${calValue}`)()</code> method is set in the <code>setPreviewValue(`${prevAns)`)</code> but if the <code>valueHasOp(calValue)</code> function returns <code>false</code> then <code>setPreviewValue(``)</code> method is made an empty string for nothing should be previewed.</p>
<p>At this point, the calculator application's main functionality works, but then there is a bug with selecting a portion of the Calculation Input to add a new number. To demonstrate the bug, see the video below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674071876702/113fa48b-a285-4ca2-a449-143875522a6a.gif" alt class="image--center mx-auto" /></p>
<p>For us to fix this bug, we'll need to know where the selection cursor is at every time on the Calculation Input (first TextInput); therefore, we need to listen to every change on the selection. Luckily, the React Native <code>&lt;TextInput /&gt;</code> component allows us to keep track of this with some props.</p>
<pre><code class="lang-javascript">...

export <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [calValue, setCalValue] = useState(<span class="hljs-string">""</span>);
    <span class="hljs-keyword">const</span> [previewValue, setPreviewValue] = useState(<span class="hljs-string">""</span>);
    <span class="hljs-keyword">const</span> [isAnswer, setIsAnswer] = useState(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> [cursorSel, setCursorSel] = useState({ <span class="hljs-attr">end</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">start</span>: <span class="hljs-number">0</span> });
    <span class="hljs-keyword">const</span> [isCursorSel, setIsCursorSel] = useState(<span class="hljs-literal">false</span>);

    ...

    return (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
            <span class="hljs-attr">style</span>=<span class="hljs-string">{[styles.input,</span> <span class="hljs-attr">ansColor</span>]}
            <span class="hljs-attr">value</span>=<span class="hljs-string">{calValue}</span>
            <span class="hljs-attr">onChangeText</span>=<span class="hljs-string">{setCalValue}</span>
            <span class="hljs-attr">selection</span>=<span class="hljs-string">{cursorSel}</span>
            <span class="hljs-attr">cursorColor</span>=<span class="hljs-string">'#8ad8d1'</span>
            <span class="hljs-attr">autoFocus</span>=<span class="hljs-string">{true}</span>
            <span class="hljs-attr">textAlign</span>=<span class="hljs-string">'right'</span>
            <span class="hljs-attr">onSelectionChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
              setIsCursorSel(true);
              setCursorSel(e.nativeEvent.selection);
            }}
            showSoftInputOnFocus={false}
          /&gt;
           <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
             <span class="hljs-attr">value</span>=<span class="hljs-string">{previewValue}...</span>
           /&gt;</span>

            ...
        <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>
    )
}
</code></pre>
<p>The above snippet shows only the changes; we'll need two new states. The first state <code>const [cursorSel, setCursorSel] = useState({ end: 0, start: 0 })</code> keeps track of the selection cursor end and start property, while the second state <code>const [isCursorSel, setIsCursorSel] = useState(false)</code> track if the selection cursor has been changed.</p>
<p>On the Calculation Input, two new props were added, <code>selection</code> which take in the <code>cursorSel</code> state and <code>onSelectionChange</code> an event handler. The <code>e.nativeEvent.selection</code> expression gets the current location of the selection cursor, which is an object like this <code>{start: 0, end: 0}</code>.</p>
<pre><code class="lang-javascript">onSelectionChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
   setIsCursorSel(<span class="hljs-literal">true</span>);
   setCursorSel(e.nativeEvent.selection);
}}
</code></pre>
<p>Even though we now keep track of when the selection cursor is moved with the <code>onSelectionChange</code> event handler, we haven't solved the bug. To solve the bug, every time a number is added to the Calculation Input, we need to know where the selection cursor is located and add the number to that spot. Therefore we'll need to change the functionality of the <code>handlePress</code> function.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handlePress = <span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</span> {
    setIsAnswer(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> corrText = text === <span class="hljs-string">"X"</span> ? <span class="hljs-string">"*"</span> : text === <span class="hljs-string">"+/-"</span> ? <span class="hljs-string">"-"</span> : text;

    setCursorSel({ <span class="hljs-attr">end</span>: cursorSel.end + <span class="hljs-number">1</span>, <span class="hljs-attr">start</span>: cursorSel.start + <span class="hljs-number">1</span> });
    setCalValue(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (prev.length !== cursorSel.end &amp;&amp; isCursorSel) {
        <span class="hljs-keyword">let</span> leftOver = prev.slice(<span class="hljs-number">0</span>, cursorSel.end);
        <span class="hljs-keyword">let</span> rightOver = prev.slice(cursorSel.end, prev.length);

        <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${leftOver}</span>`</span> + <span class="hljs-string">`<span class="hljs-subst">${corrText}</span>`</span> + <span class="hljs-string">`<span class="hljs-subst">${rightOver}</span>`</span>;
      }
      <span class="hljs-keyword">return</span> prev + <span class="hljs-string">`<span class="hljs-subst">${corrText}</span>`</span>;
    });
  };
</code></pre>
<p>Looking at the above snippet, it might look scary, but really what going on is that we first set the current selection cursor position with the <code>setCursorSel</code> function and then in the <code>setCalValue</code> function, there is a check if the previous value length <code>prev</code> is not equal to the <code>cursorSel.end</code> and <code>isCursorSel</code> is <code>true</code>.</p>
<p>Let's say the <code>prev</code> value is <code>5*4</code> and the <code>cursorSel.end</code> is at <code>0</code> , which means the selection cursor is next to <code>5</code> .</p>
<p>The <code>leftOver</code> variable would be <code>"5*4".slice(0, 0)</code> which returns an empty string <code>""</code></p>
<p>The <code>rightOver</code> variable would be <code>"5*4".slice(0,3)</code> which returns <code>5*4</code></p>
<p>Now, if the <code>text</code> parameter is <code>"4"</code>, then <code>corrText</code> would be <code>"4"</code></p>
<p>Put all together would be <code>"" + "4" + "5*4"</code> which evaluate to <code>"45*4"</code> .</p>
<blockquote>
<p>This is a hacky solutions I know, but it works 😅</p>
</blockquote>
<p>Okay, so that is it; we've successfully solved the bug; if you'll like to play around with it on your device, use the Expo snack below along with the Expo Go app; it's not suitable for the web.</p>
<iframe src="https://snack.expo.dev/embedded/@favouritejome/calculator-app3?iframeId=wt1gztt4p7&amp;preview=true&amp;platform=web&amp;theme=dark" height="100%" width="100%" style="display:block;overflow:hidden;background:#212121;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></iframe>

<p><strong>GitHub repo:</strong> <a target="_blank" href="https://github.com/jomefavourite/calculator-native/tree/blog">jomefavourite/calculator-native at blog branch (</a><a target="_blank" href="http://github.com">github.com</a><a target="_blank" href="https://github.com/jomefavourite/calculator-native/tree/blog">)</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you've followed along with the article to this point, thank you very much, and if you can't tell, I'm still new to React Native 😊, and this is a project I built by myself without a guide just to get my hands dirty, and I can say React Native is really cool.</p>
<p>If you have suggestions on how the app could be improved, please leave a comment; also, I know there are other bugs. If you can fix them, do message on Twitter <a target="_blank" href="https://twitter.com/FavouriteJome1">Favourite Jome (@FavouriteJome1)</a>.</p>
<p>Thanks for reading once again, and see you in the next <a target="_blank" href="https://favouritejome.hashnode.dev/series/lets-build-something-cool">Let's build Something Cool</a> series 🤩</p>
]]></content:encoded></item><item><title><![CDATA[First look at the GitHub CLI]]></title><description><![CDATA[We all know about Github, I presume but do we know about the Github CLI (Command Line Interface)?
The GitHub CLI is a tool I've been using recently, and I doubt many of us developers are aware of it, so we'll be looking at some of its use cases which...]]></description><link>https://blog.favouritejome.dev/first-look-at-the-github-cli</link><guid isPermaLink="true">https://blog.favouritejome.dev/first-look-at-the-github-cli</guid><category><![CDATA[GitHub]]></category><category><![CDATA[github-cli]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Mon, 05 Dec 2022 09:54:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670233842749/ktFLiCIHs.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We all know about Github, I presume but do we know about the Github CLI (Command Line Interface)?</p>
<p>The GitHub CLI is a tool I've been using recently, and I doubt many of us developers are aware of it, so we'll be looking at some of its use cases which would help boost your productivity when it comes to using Github.</p>
<p>The GitHub CLI is a tool that takes Github to the command line, allowing us to perform GitHub operations such as making a pull request (PR), creating repositories (repo) etc., that would have been done on the GitHub website directly.</p>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li>Basic knowledge of Git and GitHub</li>
<li>Basic knowledge of the terminal or the Command Line Interface (CLI)</li>
</ul>
<h2 id="heading-how-to-get-github-cli-up-on-your-machine">How to get GitHub CLI up on your machine</h2>
<p>There are various means of installing the GitHub CLI on our devices depending on the Operating System (OS) you make use of.</p>
<h3 id="heading-windows">Windows</h3>
<p>You can use these package managers or command line installers such as WinGet, and scoop, which of course, must be installed first on your machine. But if you're on Windows 10 upwards, you should have WinGet by default.</p>
<pre><code class="lang-bash">winget install --id GitHub.cli
</code></pre>
<h3 id="heading-macos">MacOS</h3>
<pre><code class="lang-bash">brew install gh
</code></pre>
<blockquote>
<p>For further instructions on how to install the GitHub CLI, please visit their <a target="_blank" href="https://github.com/cli/cli#installation">documentation</a></p>
</blockquote>
<h2 id="heading-configuring-github-cli">Configuring GitHub CLI</h2>
<p>Now that we got the CLI on our various machines, we need to be authenticated with our GitHub accounts to utilise the CLI.</p>
<p>Firstly, run the command on the terminal</p>
<pre><code class="lang-bash">gh auth login
</code></pre>
<p>When you run the command above, you'll get more prompt; the images below work you through the steps</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1669943067274/GDuJr_biP.jpg" alt="1.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1669943078447/nR0ItFrk7.jpg" alt="2.jpg" /></p>
<h2 id="heading-syntax-of-the-github-cli">Syntax of the GitHub CLI</h2>
<p>The GitHub CLI commands follow a certain basic syntax or usage, which is:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1669945224733/eRq8Vt5bT.jpg" alt="basic syntax of the GitHub CLI commands" class="image--center mx-auto" /></p>
<p><strong>gh</strong>: is the initial command, saying I want to use GitHub CLI</p>
<p><strong>command</strong>: specifies the action you'll like to take, like <strong>login</strong>, <strong>pr</strong> (pull request), <strong>browse</strong> e.t.c</p>
<p><strong>subcommand</strong>: specifies further commands that complete the command essentially. E.g.<code>gh auth login</code>, which we've used.</p>
<p><strong>[flags]</strong>: specifies additional options or arguments to the command.</p>
<h2 id="heading-github-cli-basic-commands">GitHub CLI Basic Commands</h2>
<p>There are a lot of commands that serve different GitHub operations, so we aren't going to cover all; we'll look at two commands, which I offend make use of.</p>
<h3 id="heading-gh-repo">gh repo</h3>
<p>The <code>gh repo</code> command is used for handling repositories, and it comes with lots of subcommands, such as:</p>
<ul>
<li>gh repo create</li>
<li>gh repo clone </li>
<li>gh repo delete</li>
<li>gh repo edit</li>
<li>gh repo fork</li>
<li>e.t.c</li>
</ul>
<blockquote>
<p>To view the complete lists of the <code>gh repo</code> commands, do <a target="_blank" href="https://cli.github.com/manual/gh_repo">visit the docs here</a></p>
</blockquote>
<p>Let's go over just one of the subcommands under the <code>gh repo</code> command:</p>
<h3 id="heading-gh-repo-create-flags"><code>gh repo create [&lt;name&gt;] [flags]</code></h3>
<p>The command above is to create a repository, making it private and public, with flags and lots of other cool stuff concerning a repository beyond this article's scope.</p>
<p><strong>[name]</strong>: specifies the name of the repository while</p>
<p><strong>[flags]</strong>: specifies particular arguments for the repository being created, for example, making the repo public or private</p>
<p><strong>Running the commands</strong></p>
<p>Before we run the commands, you should know that there are two modes of using this command: the interactive mode and the non-interactive mode.</p>
<p><strong>The interactive mode</strong> means you'd go through a list of questions like whether you want to clone the repo after it's been created, whether it should be a private or public repo, and other questions. <strong>Note</strong> the interactive mode doesn't take arguments, so only the command <code>gh repo create</code> is used.</p>
<p>Let's look at a step-by-step guide using the interactive mode command:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670171020004/j8avyKkwB.jpg" alt="gh repo create" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670171033469/o-DgOH5ha.jpg" alt="gh repo create" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670171039372/OAAE2vwpp.jpg" alt="gh repo create" /></p>
<p><strong>The non-interactive mode</strong> is a declarative way of specifying how the repo should be created, where the name and various flags would be specified. </p>
<p>Now, let's create a new repository just like we've done before, but this time in a non-interactive mode whereby there is no step-by-step procedure and no questions.</p>
<pre><code>gh repo create new_repo --add-readme --private -d <span class="hljs-string">"Hello this is a new repo"</span> -c
</code></pre><p>Notice I have 4 flags along with the repository name</p>
<p><strong>--add-readme</strong>: specifies you want a Readme file added to the repo, obviously 😅</p>
<p><strong>--private</strong>: specifies, hey repo, be a private repo 🔏</p>
<p><strong>-d [string]</strong>: specifies description for the repo ✍️</p>
<p><strong>-c</strong>: specifies you'll like to clone the repo once it's created ⬇️</p>
<p>Here's the output of the command:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670171875967/PlvETX0p5.png" alt="Screenshot_20221204_053636.png" /></p>
<blockquote>
<p>If you'll like to know more about how the other subcommand are to be used, please read up <a target="_blank" href="https://cli.github.com/manual/gh_repo">on their docs here</a></p>
</blockquote>
<h3 id="heading-gh-pr">gh pr</h3>
<p>The <code>gh pr</code> command is used to work with GitHub pull requests, and it comes with lots of subcommands, such as:</p>
<ul>
<li>gh pr create</li>
<li>gh pr close</li>
<li>gh pr diff</li>
<li>gh pr comment</li>
<li>gh pr reopen</li>
<li>e.t.c</li>
</ul>
<blockquote>
<p>To view the complete lists of the <code>gh pr</code> commands, do <a target="_blank" href="https://cli.github.com/manual/gh_pr">visit the docs here</a></p>
</blockquote>
<p>Let's go over just one of the subcommands under the <code>gh pr</code> command:</p>
<h3 id="heading-gh-pr-create-flags"><code>gh pr create [flags]</code></h3>
<p>The command above would be used to create a pull request, and there are two modes of running this command, just like the <code>gh repo create</code> command; we have the <strong>interactive mode</strong> and the <strong>non-interactive mode</strong>.</p>
<p><strong>Running the command</strong></p>
<p>Let's create a pull request on the <code>new_repo</code> repository we created earlier. Though in other for us to make the pull request to the repo, we must have created a new branch first because the sole purpose of a pull request is to say hey, I've made some changes would you like to merge my changes to some other branch (target branch).</p>
<p>So once you've identified that you have multiple branches, another thing to look out for is ensuring the working directory on the terminal is the directory you want to make the pull request to. That is, if the command <code>pwd</code> (print working directory) is run, it should output something like this <code>/c/Users/..../new_repo</code>. Basically, the last path should be a git repository, which in this case is <code>new_repo</code>.</p>
<p>Now, let's practicalize all this:</p>
<p><strong>Interactive mode</strong></p>
<p>Recap, so we need to create a new branch first, then make some changes, push those changes and make the pull request to the main branch from the new branch</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670178551666/vPQFxkKMT.jpg" alt="8.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670178571682/vwQ4rFRag.jpg" alt="9.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670178592711/-Lk_LODas.jpg" alt="10.jpg" /></p>
<p><strong>Non-interactive mode</strong></p>
<p>Now for this example, we write the entire command with flags such as <code>--title</code> or <code>--body</code>, which is used in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670179143955/824lOL9L9.png" alt="image.png" /></p>
<blockquote>
<p><strong>Note</strong>: if you're going to run the command above, you should have made some changes to your codebase and pushed it before creating the pull request. Also, note there are more <strong>flags</strong> when using the <code>gh pr create</code> command, to view all, <a target="_blank" href="https://cli.github.com/manual/gh_pr_create">visit the docs here</a></p>
</blockquote>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Now I believe you've got the hang of the GitHub CLI and will be willing to explore the various commands provided if you've got to this point in the article. One helpful flag to always make use of is the <code>--help</code> flag. I believe you could use it along with all the commands, which would guide you on utilising the commands instead of running to the <a target="_blank" href="https://cli.github.com/manual">documentation</a> all the time.</p>
<p>Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[First Internship Journey as a Front-End Developer and What I've Learnt]]></title><description><![CDATA[In this article, I'll share my journey to how I became a Frontend Developer Intern at a company named Vasiti.com for 5 months, how I got in, my process of getting the role and what I've leant through the internship.
After a certain amount of years in...]]></description><link>https://blog.favouritejome.dev/first-internship-journey-as-a-front-end-developer-and-what-ive-learnt</link><guid isPermaLink="true">https://blog.favouritejome.dev/first-internship-journey-as-a-front-end-developer-and-what-ive-learnt</guid><category><![CDATA[internships]]></category><category><![CDATA[interview]]></category><category><![CDATA[job search]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Thu, 30 Dec 2021 08:38:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1640807749406/1WSfZ0KuH.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I'll share my journey to how I became a Frontend Developer Intern at a company named <a target="_blank" href="https://www.vasiti.com/">Vasiti.com</a> for 5 months, how I got in, my process of getting the role and what I've leant through the internship.</p>
<p>After a certain amount of years in college, most faculties make it compulsory for students to embark on the Industrial Training Programme, where students undergo supervised practical training (real-world training) in a selected industry to learn and get acquainted with some industrial skills. I had gotten to the year where I had to undergo this training which lead to questions like where would I like to work? </p>
<p>Since I was already into the Web ecosystem, I wanted to work for a company that was utilizing Web technologies, so as for me not to do something I wasn't interested in. </p>
<h2 id="heading-how-i-got-the-internship">How I got the internship</h2>
<p>In the desperate search for a place to have my Industrial Training (IT), I went online and searched for internship roles that were web-related and Front-end Development roles. I found a lot of remote roles, physical roles through platforms like <a target="_blank" href="https://ng.indeed.com/">Indeed</a>, Google Jobs, <a target="_blank" href="https://www.myjobmag.com/">MyJobMag</a> etc then I applied to all I found meaningful, though I didn't apply to remote roles since I didn't want to work remotely.</p>
<h3 id="heading-application-process">Application process</h3>
<p>I applied by sending in my resume and a brief write up, for example saying "I'll love to be an intern at your company". Upon doing this, I made some research about the companies that interest me, like what are they doing, their goals and their mission. Here's a preview of the message I sent to the company I worked with.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638923868674/Ls8HepDY0.png" alt="Internship.png" /></p>
<p>Funny enough Vasiti.com wasn't looking for an intern when I applied, they needed a Frontend Developer. But I took a leap of faith and still sent my resume by saying I'll love to be an intern at their organization knowing fully well that the role wasn't an internship role.</p>
<blockquote>
<p>If you'll like to view the job description, responsibilities about the job when I applied, click the <a target="_blank" href="https://www.myjobmag.com/job/front-end-developer-vasiti-dotcom-3">link here</a></p>
<p>So if you're looking for an internship role and you have a company in mind, even if they aren't looking for an intern just apply and pitch yourself, who knows, you might just get your desired outcome.</p>
</blockquote>
<p>Though I didn't have a cover letter to support my resume, I made sure to include my best projects on the resume also I had the resume reviewed, all thanks to <a class="user-mention" href="https://hashnode.com/@victoria">Victoria Lo</a> and her wonderful article <a target="_blank" href="https://lo-victoria.com/the-ultimate-resume-guide-for-developers">The Ultimate Resume Guide for Developers</a> which set me to a right path.</p>
<blockquote>
<p>If you're like to view the resume, <a target="_blank" href="https://drive.google.com/file/d/1gvW04rcbKsHC8gxNC-IS7ifyC2RgUVJY/view?usp=sharing">click here</a></p>
</blockquote>
<p>Just like that, I got replies from two organizations I applied to among several organizations. Here's the feedback I got:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638926418377/mGV-GhWSA.png" alt="Vasiti.com Front End Developer Assessment.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638926408052/SEl3iyMAi.png" alt="BINCOM ACADEMY (Mobile App Trainee Developer -Internship).png" /></p>
<p>I ended up going for the company <strong>Vasiti.com</strong> since I first got a reply from them and I liked they were geared towards helping students grow as an entrepreneur as of that time, then I took their assessment which spanned 24 hrs, honestly, that day was a rush 🥴. The assessment was to build a testimonial page from the design provided and also to allow users to add testimonials.</p>
<p>That day I didn't rest until I got the web page ready and looking much like the design and also implemented adding more testimonials. I made use of React and Styled Components to accomplish the project, here's the <a target="_blank" href="https://vasiti-testimonial-app.vercel.app/">live demo</a> and <a target="_blank" href="https://github.com/jomefavourite/vasiti-testimonial-app">codebase</a></p>
<blockquote>
<p>Platforms that impacted my skills building web pages from a design template are <a target="_blank" href="https://www.frontendmentor.io/">frontendmentor.io</a> and <a target="_blank" href="https://devchallenges.io/">devchallenges.io</a>. I higher recommend these two platforms, just get a challenge and build.</p>
</blockquote>
<h3 id="heading-interview-process">Interview process</h3>
<p>On July 1st, a mail was sent to me, congratulating me on the successful assessment submission, including the interview date which was the next day 😊.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1640379528859/Ugs5lnLN-.png" alt="Interview Invitation for Front End Developer Intern Role at Vasiti.com.png" /></p>
<p>So I consulted YouTube on how an interview would be structured, what questions would be asked and how to answer them. Even though I did watch some videos and practised what I'd say, the interview didn't go as planned 🤣. You see, in those videos I watched, the questions asked weren't technical they were questions like "Tell me about yourself?", "What experience do you have?", "How do you handle stress and pressure?"</p>
<blockquote>
<p>Here's one of the videos I watched: <a target="_blank" href="https://www.youtube.com/watch?v=KCm6JVtoRdo">Interview Questions and Answers! (How to PASS a JOB INTERVIEW!)</a></p>
</blockquote>
<p>I eventually didn't practice any technical questions for the role as a Frontend Developer, which showed effect when I got to the interview seat. Also, I didn't make more research about the company, what could be improved on their website, well I guessed I believed the questions in the youtube videos I watched were what I'll be asked.</p>
<p>The next day, getting to the hot seat, faced with the CEO, CTO and HR of the company was really intimidating for me, even though they hadn't asked questions 😂. Eventually, after introductions, the questions started, firstly by the HR manager. She asked questions like how I got to know about the company, a brief introduction about myself and other questions alike.</p>
<p>Next off, technical questions by the CTO were thrown at me, mainly about React. Questions like what's the difference between a Functional Component and Class-based components, what's OOP, can hooks be used in a Class Component. But I think the very first question was how I would rate my skills with React from 1 to 10 and silly me at that time said 5.</p>
<p>Well, I guess I felt confident rating myself 5 in React as of that time and I didn't want to rate myself too low as for me to get employed, but really that lead to more follow-up questions that I couldn't give correct answers to because I was unprepared. </p>
<p>I felt bad for not practising enough, that when it came to the CEO questions I was down and while answering his questions I tried thinking deeply for an appropriate answer. I remember being asked by the CEO from the website what can I improve. Seriously, when I heard the question I couldn't think of any reasonable answer because I didn't take note of what could be improved.</p>
<p>I ended up talking about SEO (Search Engine Optimization) and saying whatever came to my mind 😂. Other questions like if I'll like to get paid as an intern at the company was asked and I eagerly said YES! 😁. Then I was asked how much I'll like to be paid, hmm, this was a tough question.</p>
<p>Initially, upon getting to the interview I had concluded I would like to be paid at least N30k per month, but weighing how the interview had gone I changed my mind and said N20k to the CEO. After responding to the question, I could see on the CEO's face a sign of relievement that I didn't go too far with the money.</p>
<blockquote>
<p>I know! probably if I had went with a price higher or stuck to N30k as I planned I might have still gotten the role, but right now it doesn't matter</p>
</blockquote>
<h3 id="heading-landing-the-job">Landing the Job</h3>
<p>After a week from the interview, almost losing hope of getting feedback, I got a mail on July 11th, welcoming me to the company. I wouldn't lie, I was really happy getting the mail that day and grateful I was accepted.</p>
<p>Then, I had to relocate from my family home to a new home closer to my workplace. The family I stayed with accepted and accommodated me very well and for that, I'm sincerely grateful to them.</p>
<p>While starting the job my salary was concluded to be N25k per month and I learnt a lot during the space of 5 months, so here are some of what I've learnt.</p>
<h2 id="heading-what-ive-learnt">What I've Learnt</h2>
<p>I'm going to share both technical and non-technical things I have learnt doing the 5 month internship</p>
<h3 id="heading-1-asking-questions-when-stuck-is-one-of-the-best-ways-to-learn">1. Asking Questions when stuck is one of the best ways to learn</h3>
<p>There were so many tasks I was given, that I literally had no idea how to tackle and solve them. Even after my supervisor has taken his time, explaining how and what I needed to do, I might still not just get it right on the first trial.</p>
<p>There was this night, I got really frustrated and left the office angry just because I couldn't complete my task, this was around the second to fourth week working at the company. </p>
<p>The next day, when I got to work with a fresh mind, I asked questions to the other Frontend Developer who is a Guru BTW, and he helped me out fixing my issue. </p>
<p>The main reason I got to the point of being frustrated was that I was stubborn and didn't want to follow my colleague's method, well being strong-headed didn't work out well 😂.</p>
<h3 id="heading-2-own-up-to-your-mistakes">2. Own up to Your Mistakes</h3>
<p>I've made some mistakes and pushed them to production 🤦‍♂️. Mistakes such as not changing an API endpoint, so when users search for a product they get the wrong product, not checking properly if the webpage is fully responsive on all devices, using a test authorization key and pushed to production.</p>
<p>Lots of mistakes, I've made but when it came to answering those mistakes, I learnt to admit that I was the cause of those issues and quickly I was able to fix them as well with some help from my colleagues.</p>
<h3 id="heading-3-acquired-knowledge-on-business-terms">3. Acquired knowledge on business terms</h3>
<p>Every morning by 9 am, Start of Business (SOB), we attend a stand-up meeting, where everyone has to talk about what they did the previous day and what they plan to do that current day. Questions during this period were also allowed.</p>
<p>I got exposed to what each department of the company does, be it the sales department, customer care, marketing department etc. Through questions and just listening I learnt a lot.</p>
<p>I got to know about setting OKR's (Objective Key Results), KPI (Key Performance Indicator) and many more organisational terms.</p>
<h3 id="heading-4-new-technologies">4. New Technologies</h3>
<p>I got to learn about new technologies I hadn't used before on the job, such as Next.js, Material UI, react-hook-form, SWR and lots more. Working with these tools daily got me acquitted with many concepts.</p>
<h3 id="heading-5-reading-an-already-written-codebase-saves-you-time">5. Reading an already written codebase saves you time</h3>
<p>Reading my colleagues code, what they've done in the past saved me a ton of time. Whenever I was tasked to do something similar to what have been done in the past, all I had to do was go read and understand what my colleagues had done.</p>
<p>From there, I could manipulate their code and achieve what I want, a win-win situation right? But honestly most times I don't understand what some code does, once I know that the solution to my problem, all I do is copy and paste, a typical trait of a developer 😏 </p>
<h3 id="heading-6-stress-and-fatigue-comes-with-the-job">6. Stress and Fatigue comes with the Job</h3>
<p>Sitting down all day, leaving the office late mostly around 6 pm - 7 pm, facing challenging tasks, all bring about stress and tiredness. Most days I felt like not doing anything cause the previous day I was stressed out.</p>
<blockquote>
<p>So this is something you might experience</p>
</blockquote>
<h3 id="heading-7-how-to-be-a-team-player">7. How to be a team player</h3>
<p>Learnt how to listen to others opinions, instead of just jumping right into coding, how to comport what I say, how does it affect my colleagues, accepting when it is totally my fault when something is wrong.</p>
<p>I got to collaborate with the backend developer, getting API endpoint from him, what parameter/data should be sent back to the backend, how's the API structured and stuff like that.</p>
<p>Collaborated with the designer, the other Frontend developer and the Full-stack developer in other to achieve our tasks.</p>
<h3 id="heading-8-working-to-get-paid-isnt-easy">8. Working to get paid isn't easy</h3>
<p>Yeah, this is something I learnt while working since this was my very first job and a means to make money from my web skills. </p>
<p>Waking up early, preparing for work by 6 am and being on the road just to get to work before 9 am and still getting home late mostly around 8 pm-ish or much more later every working day isn't easy. I applaud my parents for working and providing for me and my siblings, money is really hard to get.</p>
<hr />
<p>I could go on and on about what I've learnt during does 5 months but I'll stop here, I hope you've learnt something from my experience if you've gotten to this point of the article. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In the end, I think I've acquired a good amount of knowledge from the company. I might have been lucky to get accepted but I went for what I wanted.</p>
<p>So I'll say, go for what you want, make sure it's a place you can learn something new every day, tackle challenging problems and eventually solve them.</p>
<p>I had a wonderful team to work with, people I could learn from, a wonderful supervisor that wanted me to grow and learn, a CEO that leads by example, overall it was a wonderful experience working at the company. Grateful for the push and complicated task I was assigned 😏. Thank you <a target="_blank" href="https://vasiti.com">Vasiti.com</a></p>
<p>I'm also truly grateful to everyone that helped me in the process of looking for an IT placement, my parents, friends and family, grateful to people on Twitter that sent me applications to apply. Thank you all.</p>
<p><strong>Thanks for reading ✌</strong></p>
]]></content:encoded></item><item><title><![CDATA[Let's build Windows 11 dropdown menu using Radix Primitives]]></title><description><![CDATA[Hello there, and welcome back to the Let's Build something cool series. In this article, we'll build the Windows 11 dropdown that's displayed on the desktop. Here's a preview:
https://codesandbox.io/embed/charming-kepler-c5ejj?fontsize=14&hidenavigat...]]></description><link>https://blog.favouritejome.dev/lets-build-windows-11-dropdown-menu-using-radix-primitives</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-windows-11-dropdown-menu-using-radix-primitives</guid><category><![CDATA[Accessibility]]></category><category><![CDATA[components]]></category><category><![CDATA[React]]></category><category><![CDATA[UI]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sat, 04 Dec 2021 15:43:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638629807118/H6FjLekfy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello there, and welcome back to the <a target="_blank" href="https://favouritejome.hashnode.dev/series/lets-build-something-cool">Let's Build something cool series</a>. In this article, we'll build the Windows 11 dropdown that's displayed on the desktop. Here's a preview:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/embed/charming-kepler-c5ejj?fontsize=14&amp;hidenavigation=1&amp;theme=dark">https://codesandbox.io/embed/charming-kepler-c5ejj?fontsize=14&amp;hidenavigation=1&amp;theme=dark</a></div>
<p> </p>
<blockquote>
<p>**Note:**The code sandbox is best viewed on a large screen</p>
</blockquote>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li><p>Basic knowledge of React.js</p>
</li>
<li><p>Basic knowledge of the command line</p>
</li>
</ul>
<h2 id="heading-back-story-for-the-project">Back story for the project</h2>
<p>While watching the Next.js Conference, <a target="_blank" href="https://twitter.com/@peduarte">Pedro Duarte</a> spoke on the topic: <a target="_blank" href="https://www.youtube.com/watch?v=pcMYcjtWwVI&amp;t=544s">"So You Think You Can Build A Dropdown?"</a> where he built an accessible dropdown making use of a library called <a target="_blank" href="https://www.radix-ui.com/">Radix</a></p>
<h2 id="heading-whats-radix">What's Radix</h2>
<p>Radix is an open-source UI component library for building high-quality, accessible design systems and web apps that are un-styled. Styles can be applied using any styling solution be it plain CSS, SCSS, Tailwind CSS and so on.</p>
<p>Some of the UI components they provide are: <a target="_blank" href="https://www.radix-ui.com/docs/primitives/components/accordion">Accordion</a>, <a target="_blank" href="https://www.radix-ui.com/docs/primitives/components/dialog">Dialog</a>, <a target="_blank" href="https://www.radix-ui.com/docs/primitives/components/dropdown-menu">Dropdown Menu</a> and lots more. Do check out their website to see more components: <a target="_blank" href="https://www.radix-ui.com/">Radix</a></p>
<h2 id="heading-setup">Setup</h2>
<p>First thing first, we'll need a react project and do this, we need to install react with the command below:</p>
<pre><code class="lang-bash">npx create-react-app windows-dropdown
</code></pre>
<p>Now that we've got our react app setup, we'll need to install the primitive next, which in this case is the <em>dropdown-menu</em>. Run the command below to get it installed:</p>
<pre><code class="lang-bash">npm install @radix-ui/react-dropdown-menu
</code></pre>
<p>We'll need the icons Radix also provides, so let's install the icon library.</p>
<pre><code class="lang-bash">npm install @radix-ui/react-icons
</code></pre>
<blockquote>
<p>**Note: ** Using the Radix icon library isn't mandatory, you could use SVG or images of your choice.</p>
</blockquote>
<h2 id="heading-building-the-dropdown-component">Building the dropdown component</h2>
<p>Now, let's move to the <code>src</code> directory to create a <code>components</code> directory and then a file named <code>WindowsDropdown.js</code> (feel free to name the file name as you please).</p>
<p>In the <code>WindowsDropdown.js</code> file, let's get a functional component setup like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WindowsDropdown</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          Here's the windows dropdown component
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
   )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> WindowsDropdown;
</code></pre>
<p>Now, let's import the <code>WindowsDropdown</code> component in the <code>App.js</code> file, in order to view the <code>WindowsDropdown</code> component on the browser.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> WindowsDropdown <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/WindowsDropdown"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">WindowsDropdown</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Run the command below to get the application running on the browser</p>
<pre><code class="lang-bash">npm start
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638434395933/2hg3Ewxwm.png" alt="screely-1638434371517.png" /></p>
<h3 id="heading-how-to-get-the-dropdown-setup">How to get the Dropdown setup</h3>
<p>Before getting started with the windows dropdown component, let's demo how the Radix dropdown will be set up.</p>
<blockquote>
<p><strong>Note:</strong> You don't have to type in these code in your editor since it's just to explain how the library is used</p>
</blockquote>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> DropdownMenu <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-dropdown-menu"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WindowsDropdown</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>

         <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
                 New Tab
            <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
                 New Tab
            <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span></span>
   )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> WindowsDropdown;
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/sample1-yc53n?file=/src/styles.css">https://codesandbox.io/s/sample1-yc53n?file=/src/styles.css</a></div>
<p> </p>
<p>From the demo above, you'll notice the dropdown doesn't have styles applied. Try navigating through the items with the keyboard arrows <em>(up key and down key) when</em> the button is clicked; you'll notice the first item is focused, then when moved to the next item, it's also focused well; this will only work on a desktop, not mobile. This shows how accessible the library is.</p>
<ul>
<li>Firstly, we import all the various component parts that come with the dropdown primitive with the asterisk sign given an alias/label <strong>DropdownMenu</strong>  </li>
</ul>
<pre><code class="lang-bash">import * as DropdownMenu from <span class="hljs-string">"@radix-ui/react-dropdown-menu"</span>;
</code></pre>
<blockquote>
<p><strong>Note:</strong> Each component could be gotten individually like this: <code>import {Root} from "@radix-ui/..."</code></p>
</blockquote>
<ul>
<li><p><code>DropdownMenu.Root</code><br />  Contains all the parts of the dropdown menu, basically housing all parts.</p>
</li>
<li><p><code>DropdownMenu.Trigger</code><br />  This is basically a button that toggles the dropdown menu when clicked.</p>
</li>
<li><p><code>DropdownMenu.Content</code><br />  This is the component that pops out when the dropdown menu is open.</p>
</li>
<li><p><code>DropdownMenu.Item</code><br />  This component contains the dropdown menu items.</p>
</li>
</ul>
<p>Now let's go over a demo with a nested dropdown.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> DropdownMenu <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-dropdown-menu"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WindowsDropdown</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>New Tab<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>New Tab<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.TriggerItem</span>&gt;</span>
            View more dropdown
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.TriggerItem</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>Auto arrange icons<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Separator</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>Align icons to grid<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> WindowsDropdown;
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/sample2-lb99r?file=/src/components/WindowsDropdown.js:0-918">https://codesandbox.io/s/sample2-lb99r?file=/src/components/WindowsDropdown.js:0-918</a></div>
<p> </p>
<p>From the codesandbox above, you'll notice when the <strong>view more dropdown</strong> text is hovered on / navigated to through the arrow keys, another dropdown is shown. That's a nested dropdown, now, let's walk through how the code snipper is constructed.</p>
<ul>
<li><code>DropdownMenu.TriggerItem</code><br />  An item that opens a submenu. Used in combination with a nested <code>DropdownMenu</code>. Must be rendered inside <code>DropdownMenu.Root</code>.</li>
</ul>
<pre><code class="lang-js"> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.TriggerItem</span>&gt;</span>
            View more dropdown
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.TriggerItem</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span></span>
  );
</code></pre>
<h3 id="heading-styling-the-dropdown">Styling the Dropdown</h3>
<p>Styling the component is very easy, all we need is to apply classes <code>className</code> to each component we will like to style. Let's see this in action:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> DropdownMenu <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-dropdown-menu"</span>;
<span class="hljs-keyword">import</span> { ChevronRightIcon } <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-icons"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WindowsDropdown</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"root"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Trigger</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"trigger"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Trigger</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"content"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"item"</span>&gt;</span>Tab One<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"item"</span>&gt;</span>Tab Two<span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.TriggerItem</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"item"</span>&gt;</span>
            View
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">marginLeft:</span> "<span class="hljs-attr">auto</span>" }}&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">ChevronRightIcon</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.TriggerItem</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Content</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"content content--drop"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"item"</span>&gt;</span>
              Auto arrange icons
            <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Separator</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">DropdownMenu.Item</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"item"</span>&gt;</span>
              Align icons to grid
            <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Item</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Content</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">DropdownMenu.Root</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> WindowsDropdown;
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  ...
}

<span class="hljs-selector-class">.trigger</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span> <span class="hljs-number">2rem</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.61</span>);
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid black;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">20px</span>;
}

<span class="hljs-selector-class">.content</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#000000a2</span>;
  <span class="hljs-attribute">padding-block</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">5px</span> <span class="hljs-number">6px</span> <span class="hljs-number">5px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.199</span>);
  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">224</span>, <span class="hljs-number">224</span>, <span class="hljs-number">224</span>);
  <span class="hljs-attribute">min-width</span>: <span class="hljs-number">300px</span>;
}

<span class="hljs-selector-class">.content--drop</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#000000ab</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid black;
}

<span class="hljs-selector-class">.content--drop</span> <span class="hljs-selector-class">.item</span> {
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">25px</span>;
  <span class="hljs-attribute">justify-content</span>: space-between;
}

<span class="hljs-selector-class">.content</span> &gt; * + * {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0.8rem</span>;
}

<span class="hljs-selector-class">.item</span> {
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span> <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">margin-inline</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">cursor</span>: default;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
}

<span class="hljs-selector-tag">div</span> <span class="hljs-selector-attr">[role=<span class="hljs-string">"menuitem"</span>]</span>,
<span class="hljs-selector-tag">div</span> <span class="hljs-selector-attr">[role=<span class="hljs-string">"menuitemradio"</span>]</span> {
  <span class="hljs-attribute">outline</span>: none;
}

<span class="hljs-selector-tag">div</span> <span class="hljs-selector-attr">[role=<span class="hljs-string">"menuitem"</span>]</span><span class="hljs-selector-pseudo">:focus</span>,
<span class="hljs-selector-tag">div</span> <span class="hljs-selector-attr">[role=<span class="hljs-string">"menuitemradio"</span>]</span><span class="hljs-selector-pseudo">:focus</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#46464681</span>;
}

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-reduced-motion:</span> no-preference) {
  <span class="hljs-selector-class">.content</span> {
    <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">400ms</span>;
    <span class="hljs-attribute">animation-timing-function</span>: <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.16</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0.3</span>, <span class="hljs-number">1</span>);
    <span class="hljs-attribute">will-change</span>: transform, opacity;
  }

  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"top"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideDownAndFade;
  }

  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"right"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideLeftAndFade;
  }
  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"bottom"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideUpAndFade;
  }
  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"left"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideRightAndFade;
  }
}

<span class="hljs-keyword">@keyframes</span> slideUpAndFade {
  0% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(<span class="hljs-number">9px</span>);
  }
  100% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(<span class="hljs-number">0</span>);
  }
}

<span class="hljs-keyword">@keyframes</span> slideRightAndFade {
  0% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(-<span class="hljs-number">2px</span>);
  }
  100% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>);
  }
}

<span class="hljs-keyword">@keyframes</span> slideDownAndFade {
  0% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(-<span class="hljs-number">2px</span>);
  }
  100% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(<span class="hljs-number">0</span>);
  }
}

<span class="hljs-keyword">@keyframes</span> slideLeftAndFade {
  0% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">2px</span>);
  }
  100% {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>);
  }
}
</code></pre>
<p>Notice the use of the <code>@keyframe</code> rule from the snippet above. So it's possible to add animations also using Radix, which is super cool.</p>
<p>Also, from the CSS snippet, you'll notice the use of attribute selectors such as:</p>
<pre><code class="lang-css">  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"top"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideDownAndFade;
  }

  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"right"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideLeftAndFade;
  }
  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"bottom"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideUpAndFade;
  }
  <span class="hljs-selector-attr">[data-state=<span class="hljs-string">"open"</span>]</span><span class="hljs-selector-attr">[data-side=<span class="hljs-string">"left"</span>]</span> {
    <span class="hljs-attribute">animation-name</span>: slideRightAndFade;
  }
</code></pre>
<p>The reason why there are various alternatives to the <code>data-side</code> attribute, which is added to the <code>DropdownMenu.Component</code> element is because depending on the space available for the dropdown, it'll adjust to the viewport to either show at the top, right, left, or bottom view, pretty much as you'll have it on Windows 11.</p>
<p>Eg:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638710622980/W5Rc5ISbA.png" alt="React App (2).png" /></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/sample3-2cnwt?file=/src/components/WindowsDropdown.js:0-1240">https://codesandbox.io/s/sample3-2cnwt?file=/src/components/WindowsDropdown.js:0-1240</a></div>
<p> </p>
<h2 id="heading-windowsdropdown-conclusion">WindowsDropdown Conclusion</h2>
<p>Here's the complete version for the windows dropdown below. Feel free to go through the code sandbox and if you have any questions concerning the project, feel free to ask. <strong>Thanks for reading,</strong> and see you in the next <a target="_blank" href="https://favouritejome.hashnode.dev/series/lets-build-something-cool">Let's Build something cool series</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/windows-dropdown-c5ejj?file=/src/components/WindowsDropdown.js">https://codesandbox.io/s/windows-dropdown-c5ejj?file=/src/components/WindowsDropdown.js</a></div>
<p> </p>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><p><a target="_blank" href="https://www.radix-ui.com/docs/primitives/components/dropdown-menu">Radix Docs</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=pcMYcjtWwVI&amp;t=544s">Next.js Conference - So You Think You Can Build A Dropdown?</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[VS Code Version Control: Understanding the basics of  Git operations # 1]]></title><description><![CDATA[Visual Studio Code (VS Code) is one of the most used Integrated Development Environments (IDE) with lots of features which most users don't know about (including myself, I can't say I've used all the features that VS Code provides 😃).
So in this art...]]></description><link>https://blog.favouritejome.dev/vs-code-version-control-understanding-the-basics-of-git-operations-1</link><guid isPermaLink="true">https://blog.favouritejome.dev/vs-code-version-control-understanding-the-basics-of-git-operations-1</guid><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Git]]></category><category><![CDATA[version control]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Mon, 29 Nov 2021 06:34:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638050548475/iyb5t0z_w.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Visual Studio Code (VS Code) is one of the most used Integrated Development Environments (IDE) with lots of features which most users don't know about (including myself, I can't say I've used all the features that VS Code provides 😃).</p>
<p>So in this article, we'll look into a feature we developers would probably use frequently in VS Code: the Version Control feature called Source Control in VS Code. Understanding some of the various operations, how they translate to the Git commands and how the operations are useful for managing source control in VS Code.</p>
<blockquote>
<p><strong>Note:</strong> Please feel free to jump around the Table of Content cause you might not need all the information if you already know about them, but you could read all and probably learn something new</p>
</blockquote>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li>Basic knowledge of Git</li>
<li>Basic knowledge of VS Code interface</li>
</ul>
<h2 id="heading-whats-the-source-control-or-the-version-control">What's the Source Control or the Version Control</h2>
<p>The Source Control or Version Control is a system used to manage all activities carried out on a computer program which is also referred to as a human-readable program known as the <strong>source code</strong>.</p>
<blockquote>
<p>If you'll like to read more about what Source Control or Version Control is, please do <a target="_blank" href="https://en.wikipedia.org/wiki/Version_control">here</a>.</p>
</blockquote>
<h2 id="heading-source-control-panel-on-vs-code">Source Control Panel on VS code</h2>
<p>VS Code uses Git right out of the box as its primary Version Control system, which means you'll need Git installed on your PC before using Git through the Source Control sidebar on VS Code.</p>
<p>To get Git on your machines, follow the links below:</p>
<p><strong>For Windows OS</strong></p>
<p><a target="_blank" href="https://git-scm.com/download/win">Download Git for Windows</a></p>
<p><strong>For Linux OS</strong></p>
<p><a target="_blank" href="https://git-scm.com/download/linux">Download Git for Linux</a> or run the command on the terminal</p>
<pre><code class="lang-bash">sudo apt install git
</code></pre>
<p><strong>For Mac OS</strong></p>
<p><a target="_blank" href="http://git-scm.com/download/mac">Download Git for Mac</a></p>
<p>Now that we've got Git installed on our various machines, we need to config Git to our machine. Don't worry; this step is a one-time process.</p>
<h3 id="heading-setting-up-git-for-vs-code">Setting up Git for VS code</h3>
<p>Firstly, we need to set up our identity through the terminal, which can be opened/closed on VS code by using <code>(Ctrl + J)</code>. Our username and email address are needed to set up our identity for Git.</p>
<pre><code class="lang-bash">git config --global user.name <span class="hljs-string">"John Doe"</span>
git config --global user.email johndoe@example.com
</code></pre>
<blockquote>
<p><strong>Note:</strong> Please do change <code>" John Doe"</code> to your username as it is on Github and also the email address <code>johndoe@example.com</code> to your email address</p>
</blockquote>
<p>The next step is configuring the code editor, which is being used to access Git; since we're using VS code, we input the command below into the terminal.</p>
<pre><code class="lang-bash">git config --global core.editor <span class="hljs-string">"code --wait"</span>
</code></pre>
<blockquote>
<p>If for any reason you're making use of a different editor, do visit <a target="_blank" href="https://git-scm.com/book/en/v2/Appendix-C%3A-Git-Commands-Setup-and-Config#ch_core_editor">here listing out the commands for other editors</a></p>
</blockquote>
<p>Lastly, we need to set up the default branch name. Recently, the default Git branch name was changed to <code>main</code> from <code>master</code>, so to configure the branch name, we make use of the command:</p>
<pre><code class="lang-bash">git config --global init.defaultBranch main
</code></pre>
<p>That's it! Git is fully configured on our machines; we can now go back to explore the Source Control Panel.</p>
<blockquote>
<p><strong>Note:</strong> <a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup">Read more about Getting Started First Time Git Setup</a></p>
</blockquote>
<h2 id="heading-working-with-the-source-control-panel">Working with the Source Control Panel</h2>
<p>Now that we know what Source Control is let's dive into VS Code and explore the various options that it provides.</p>
<p>The source control panel can be accessed using the keys <code>(Ctrl+Shift+G)</code> or by clicking the icon below on VS code.</p>
<p>While working on a directory/folder in VS code and having the source control sidebar opened, two options will be shown, which are:</p>
<ul>
<li><strong>Initialize Repository</strong></li>
<li><strong>Publish to Github</strong></li>
</ul>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048077887/TrRUzhAaX.png" alt="source-control-option.png" />

</center>

<p><strong>Initialize Repository</strong> when clicked create a <code>.git</code> folder, which is hidden by default in the working directory (or current folder being used) except you turn on the option of showing all hidden files on your PC file explorer, that's when it's visible.</p>
<p>The <code>.git</code> folder contains all the necessary information for a project to be recognized as a version control project, information about commits, branches, remote repository addresses etc are all managed in the <code>.git</code> folder.</p>
<p>The equivalent of clicking on the <strong>Initialize Repository</strong> button is the command below, which can be run on the terminal.</p>
<pre><code class="lang-bash">git init
</code></pre>
<p>The <strong>Publish to Github</strong> button when clicked, pops out a dialog for entering a repository name. By default, the name of the folder housing the project files would be selected as the name of the repository but it's changeable.</p>
<blockquote>
<p><strong>Note:</strong> you can't publish to Github if you've not connected VS code to Github.</p>
</blockquote>
<h3 id="heading-connect-github-with-vs-code">Connect Github with VS code</h3>
<p>There are various means to connect VS Code to GitHub, well we'll go through just one means, which is clicking on the <strong>Accounts</strong> icon, at the bottom of the sidebar.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048145040/MJeqmiPQY.png" alt="account.png" />

</center>

<p>Then we click on the <strong>Sign in to Sync Settings</strong> option which present us with a pop-up, signifying if we'll like to sign up with Microsoft or Github.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048168920/-uiIr5QFV.png" alt="pop-up-signup.png" />

</center>

<p>Let's signup with Github, upon clicking on the option we will be redirected to the browser window, where we are to click on the <strong>continue green button</strong>, which then signs VS code with Github. To confirm it worked correctly, go to the "Accounts Icon" on the sidebar once more, this time you should find your GitHub username displayed.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048226411/Y8f4g-p4n.png" alt="signed-up.png" />

</center>

<p>Great! We've been able to completely get VS code up and running with Git and Github. Now let's look into the various features that VS code offers through the Source Control panel.</p>
<h2 id="heading-recording-changes-to-git">Recording Changes to Git</h2>
<p>When a project is initialized with Git either by clicking on the <strong>Initialize Repository</strong> or running the command <code>git init</code>, all the files or folders in the current directory move to an <strong>Untracked State (U)</strong> shown underneath the <strong>Changes Dropdown</strong> at the Source Control Panel.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048286878/i_a2-rc7y.png" alt="changes.png" />

</center>

<blockquote>
<p><strong>Note:</strong> the <code>U</code> at the right side of each file from the image above means <strong>Untracked</strong>, and this shows on files that Git doesn't recognize.</p>
<p><strong>Remember:</strong> the <code>.git</code> folder is created once git is initialized in a folder, which keeps track of all the files</p>
</blockquote>
<p>Let's go over some features, which are accessed by icons on the files.</p>
<h3 id="heading-discard-changes">Discard Changes</h3>
<p>Discarding changes on a file or files simply means removing the file/files from the <strong>changes dropdown</strong>, deleting all changes made to the files that haven't been committed. In this case, we've not committed our files and there still in the <strong>Untracked State</strong> so if the files were to be discarded all the files will be deleted, so be really sure you want to discard a file or the entire files to be committed.</p>
<blockquote>
<p><strong>Note:</strong> To discard changes, you make use of the hook-like icon shown below:</p>
</blockquote>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048309191/Zug-I5qvY.png" alt="discard-changes.png" />

</center>

<blockquote>
<p><strong>Note:</strong> Each file underneath the <strong>Changes Dropdown</strong> also have the Discard icon</p>
</blockquote>
<h3 id="heading-stage-changes">Stage Changes</h3>
<p>Stage changes mean that the file or the files are to be tracked by git. At this point, the file(s) are in the <strong>Tracking State</strong>, which means git recognizes that these files would be committed.</p>
<blockquote>
<p><strong>Note:</strong> The files in the Staged Changes dropdown only shows those changes/files to be committed or rather that are being tracked by git</p>
</blockquote>
<p>You must have used the command shown below if you've ever used git before. All you're doing with the command is to tell git, hey, I'll like you to keep track of these files or a file, which means you're staging the file/files.</p>
<pre><code class="lang-bash">git add &lt;name of file&gt;
</code></pre>
<p>To add file(s) to the Stage Changes on VS code, you click on the <strong>+</strong> icon on each file or on the Changes dropdown.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048351623/lXlzeiy5C.png" alt="stage-changes-icon.png" />

</center>

<p>From the image above, I'm going to stage both account.png and changes.png files. By doing this, a new dropdown would be created named the <strong>Staged Changes</strong></p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048374029/mHRnDtUsV.png" alt="staged-changes-2.png" />

</center>

<blockquote>
<p>Notice the <strong>A</strong> letter added to the files at the Staged Changes dropdown, it means <strong>Added</strong>, which denotes that git is keeping track of the files</p>
</blockquote>
<h2 id="heading-committing-files">Committing Files</h2>
<p>While following Git command instructions, here's how we'll commit a file/files to Git:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"First Commit"</span>
</code></pre>
<p>Now using VS code, in order to commit out staged files which are <code>account.png</code> and <code>changes.png</code>, we go to the message input at the top of the Source Control Panel.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638051772942/bPilkbVIj.png" alt="commit-input.png" />

</center>

<p>Then we type in a message like "First Commit", then click in the <strong>checkmark</strong> icon to commit the files.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048394565/4y2SPqmzD.png" alt="commit.png" />

</center>

<p>Once the Staged changes files have been committed, the files wouldn't be seen anymore on the Source Control panel, because Git now recognizes those files as its own.</p>
<h2 id="heading-publishing-to-github">Publishing to Github</h2>
<p>To publish the committed files to Github, we'll need to move to VS code Status Bar, right at bottom of the IDE.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048424415/zYNVsPl_D.png" alt="status-bar.png" />

</center>

<blockquote>
<p><strong>Notice:</strong> from the image above, it says "blog (Git) - Publish to Github". This is because my working directory/folder is named <strong>blog</strong> that's why you can see the blog there. Also, whatever the working directory name is, that will be taken as the default repository name but still changeable.</p>
</blockquote>
<p>The next step would be to click on the icon next to the branch name which is <strong>main</strong>. When the icon is clicked there would be a pop up prompting you to sign up using Github.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048450631/uFViSSMUx.png" alt="prompt.png" />

</center>

<p>Click on <strong>Allow</strong>, which then redirect you to the browser, click on the continue button and that's it, next off would be to input the repository name.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048468533/ZgYkp_TbP.png" alt="repository-name.png" />

</center>

<p>From the image above, the repository name is "vscode-test", then you can decide if you'll like the repository to be private or public, once you either pick private or public it should show an indication at the right bottom view of VS code that the repository is publishing.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048490476/_6zntb9SX.png" alt="success.png" />

</center>

<p>Once it shows "successfully published...", you can open Github to view the newly created repository.</p>
<center>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638048507087/FpTE_Jf7Q.png" alt="vs-code.png" />

</center>

<h2 id="heading-conclusion">Conclusion</h2>
<p>We've covered how to set up Git in VS Code, how to initialize a repository and then publish the repository. In the next part of the article, we'll look into more advanced operations like Stashing, Switching between branches, Synchronization and many more.</p>
<p>Thanks for reading! I hope you find the article useful and don't forget to like and share the article.</p>
<p>See you in the next article! 👋</p>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><a target="_blank" href="https://code.visualstudio.com/docs/editor/versioncontrol#_initialize-a-repository">Using Version Control in VS Code</a></li>
<li><a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup">Getting Started - First-Time Git Setup</a></li>
<li><a target="_blank" href="https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository">Git Basics - Recording Changes to the Repository</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Introducing PlanDone - Getting plans done]]></title><description><![CDATA[Hello everyone 👋, this article is all about a fun project I decided to take to the next level by making it a Full Stack Application (which is my first) from just a school assignment project.
What's PlanDone
PlanDone is a platform made for Students w...]]></description><link>https://blog.favouritejome.dev/introducing-plandone-getting-plans-done</link><guid isPermaLink="true">https://blog.favouritejome.dev/introducing-plandone-getting-plans-done</guid><category><![CDATA[Productivity]]></category><category><![CDATA[side project]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sun, 10 Oct 2021 17:24:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1633833166331/AJAZ7gfas.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone 👋, this article is all about a fun project I decided to take to the next level by making it a Full Stack Application (which is my first) from just a school assignment project.</p>
<h2 id="heading-whats-plandone">What's PlanDone</h2>
<p>PlanDone is a platform made for Students who would like to learn smart, be productive and access everything they need while studying in one place.</p>
<p>By giving students the ability to save their notes, tasks and forecast their Cumulative Grade Point Average (CGPA) score, which can all be accessed at any time. So now you can make sure you Plan and then complete (Done) 😏.</p>
<p><strong><em><a target="_blank" href="https://github.com/jomefavourite/PlanDone">Github Repo</a> / <a target="_blank" href="https://plandone-student.herokuapp.com/">Live Demo</a></em></strong></p>
<h2 id="heading-inspiration-for-the-plandone">Inspiration for the PlanDone</h2>
<p>The year 2020 at December, Hashnode hosted a Christmas Hackathon, where an amazing project was built by <a class="user-mention" href="https://hashnode.com/@rutikwankhade">Rutik Wankhade</a> - <em><a target="_blank" href="https://blog.rutikwankhade.dev/how-i-built-my-own-productivity-app">How I built my own productivity app</a></em> which is a Productive app extension for browsers I used for quite a while.</p>
<p>It's a great extension to quickly take notes, fill in tasks and so on. I really loved the idea behind the project so that's how I came about building <strong>PlanDone</strong>.</p>
<h2 id="heading-back-story-tldr">Back story TL;DR</h2>
<p>So at school, I took a Web Design class which is compulsory for all CS majors and at the end of that semester, we were tasked to come up with an idea for a project, using HTML, CSS, and JS which we were taught in class. </p>
<p>After submitting about 3 project ideas to my lecturer, all were rejected for reasons I would never know :), then I thought of building an application that ties towards productivity because I could be really unproductive. Meanwhile, I was using <a class="user-mention" href="https://hashnode.com/@rutikwankhade">Rutik Wankhade</a> project as my browsers extension at that time and that's how I got the idea. I submitted the project idea to my lecturer and it got accepted 🎊.</p>
<p>Then, I built the frontend aspect <em>(more context below)</em>, making use of the browser's local storage feature to store users notes, tasks and links so that I could submit the assignment.</p>
<p>At this time, I was exploring backend technologies, so I said to myself, why don't I put my learnings into a project. So that's how the challenge started, making my first Full Stack Application.</p>
<h2 id="heading-features-of-plandone">Features of PlanDone</h2>
<p><strong>1. Creating Notes</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632876038604/lLMC_6OkM.png" alt="Screenshot from 2021-09-29 01-38-55.png" /></p>
<p>The notes created comes in different colours with the help of <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">Syntactically Awesome Style Sheets</a> features and a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout">Masonry Layout</a> which I think is pretty cool.</p>
<p>All notes created can be edited and deleted, also notes are written in markdown format if signed up to the platform, <em>that's a special feature 😃</em></p>
<p><strong>2. Creating Tasks</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633826994189/yTfmlaBNG.png" alt="Screenshot from 2021-10-10 01-48-49.png" /></p>
<p>Tasks could be anything you'll like to do, just add it with a deadline date. Once done, you click on the checkbox to mark it has done.</p>
<p><strong>3. CGPA Forecaster</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633827597523/OMZnYhYiR.png" alt="Screenshot from 2021-10-10 01-56-12.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633827650336/U5exjkDLU.png" alt="Screenshot from 2021-10-10 01-56-26.png" /></p>
<p>With this feature, students can easily see the score they need to work towards from their previous grades.</p>
<blockquote>
<p>This was a project done for Hashnode Christmas Hackathon 2020, view the article for the project here: <a target="_blank" href="https://favouritejome.hashnode.dev/cgpa-result-forecaster-hackathon-project">CGPA Result Forecaster - Hackathon Project</a></p>
</blockquote>
<p><strong>4. Creating Links</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633828324272/g0y2Q2Tzi.png" alt="Screenshot from 2021-10-10 02-05-17.png" /></p>
<p>The idea here is to add links to projects/articles/anything really, you might easily forget, this way you never lose a link you wanted to check out.</p>
<blockquote>
<p><strong>Quick Note</strong> <br />
All the features above work both when a user signs in to the application and when they aren't signed in, the only caveat will be without signing in all information will be lost.</p>
<p><strong>Also don't forget to give the project a star ⭐, if you think it's a fun project like I do 😎 - <a target="_blank" href="https://github.com/jomefavourite/PlanDone">https://github.com/jomefavourite/PlanDone</a></strong></p>
</blockquote>
<h2 id="heading-built-with">Built With</h2>
<ul>
<li><strong><a target="_blank" href="https://nodejs.org/en/">Node.js</a></strong> for authentication, routing.</li>
<li><strong><a target="_blank" href="https://expressjs.com/">Express</a></strong> for ease while working with Node.js</li>
<li><strong><a target="_blank" href="https://ejs.co/">EJS</a></strong>: A template engine language that generates HTML markup with plain JavaScript. </li>
<li><strong><a target="_blank" href="https://sass-lang.com/">SASS</a></strong>: Sass is a preprocessor scripting language that is interpreted or compiled into Cascading Style Sheets.</li>
<li><strong><a target="_blank" href="https://www.mongodb.com/">MongoDD/Mongoose</a></strong> for managing, storing or retrieving information.</li>
<li><strong><a target="_blank" href="http://heroku.com/">Heroku</a></strong> for hosting the application.</li>
</ul>
<h2 id="heading-planning-building-and-deploying">Planning, Building and Deploying</h2>
<p>Here's where all the fun started, my first commit was on <strong>Jun 21, 2021,</strong> which was the time I had started making the project a Full Stack Application.</p>
<p>There was a lot of back and forth movement while planning and building the project, lots of tools were added and removed. I tried different tools, exploring as I build, which I'll say is good but it would have been better if I had my plans all laid out. </p>
<p><em>Leave a comment below, which you feel is better - Exploring different tools while you build or Having predefined tools to be used.</em></p>
<ul>
<li><h3 id="heading-planning">Planning:<br /></h3>
<p>Since I already had an idea of what I wanted to build from <a class="user-mention" href="https://hashnode.com/@rutikwankhade">Rutik Wankhade</a> Project: <em><a target="_blank" href="https://blog.rutikwankhade.dev/how-i-built-my-own-productivity-app">How I built my own productivity app</a></em>, it was easy to pick some fundamental tools I did use like EJS, Node.js, Express, SASS etc.<br />
<br />
Also, I created designs for the project with the help of <a target="_blank" href="https://figma.com">Figma</a>, first I did the wireframe for each page of the project.
<br />
</p><blockquote>
The wireframe was a requirement for school. If you'll like to know more about wireframe, <a target="_blank" href="https://www.youtube.com/watch?v=2hQA1ZsGAH8">click here - How to wireframe a website</a>
</blockquote>
After completion of the wireframe, I moved then to the mockup of the website, which is a high-fidelity simulation of how I want the website to look.<br />
<br />
View the <a target="_blank" href="https://www.figma.com/file/eyezgXHOUpwcu9n0tpT8F4/Student-Productive-Website?node-id=0%3A1">Wireframe</a>/<a target="_blank" href="https://www.figma.com/file/eyezgXHOUpwcu9n0tpT8F4/Student-Productive-Website?node-id=55%3A72">Mockup</a> Designs<p></p>
</li>
<li><h3 id="heading-building">Building:<br /></h3>
<p>My building process started by setting up a Node application and figuring out how to set up Google authentication for the application, getting users Google data and tying their data into a database, so a user sees his/her information saved to PlanDone.
</p><blockquote>
<strong>Quick Note:</strong> Before figuring out the authentication processes, I had already done the Frontend aspect of the project where I made use of HTML, CSS, JS and also the browser Local Storage for store users information.
</blockquote>
With the help of some videos on YouTube, I was able to configure Google's authentication using <em>passport-google-oauth2</em> which is Google's strategy for signing up into web applications, more on that on their <a target="_blank" href="http://www.passportjs.org/docs/google/">documentation</a>. <br />
<br />
After I had figured out the authentication process, I moved into setting up my database, where I made use of MongoDB which is a NoSQL database making use of JSON-like documents with optional schemas. More on MongoDB here -<em><a target="_blank" href="https://blog.teachmebro.com/building-a-crud-application-using-node-js-and-mongodb-atlas">Building A CRUD Application Using Node JS And MongoDB Atlas</a></em> by <a class="user-mention" href="https://hashnode.com/@altafshaikh">Altaf Shaikh</a>.<br />
<br />
Thereafter I moved to implement other features I thought were cool, broke a lot of things, figured them out and generally learnt new things in the process. By the way, I made use of <a target="_blank" href="https://ejs.co">EJS</a> which is a template engine language that generates HTML markup with plain JavaScript but in this case, I made use Node.js.<br />
<br />
Lastly, I had a lot of fun playing with SASS special features, creating custom Mixins, functions and the likes. If you'll like to read more about SASS, I've got an article here - <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">Write CSS with Superpowers Using Sass</a>.<p></p>
</li>
<li><h3 id="heading-deploying">Deploying<br /></h3>
<p></p><blockquote>
This was the most stressful part, at some point, I gave up for a while and continued trying once again.
</blockquote>
So the project is deployed to both Vercel and Heroku. It seems Vercel doesn't support <strong>EJS</strong>, so I couldn't get it running with Vercel, then I moved to Heroku. Heroku gave me a tough time, I just couldn't figure out why I wasn't able to view the project live. Even now I don't know what I did to make it work 😅, but it works finally after a series of errors.<p></p>
</li>
</ul>
<h2 id="heading-resources-used-to-learn">Resources used to Learn</h2>
<ul>
<li><div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/playlist?list=PL4cUxeGkcC9jsz4LDYc6kv3ymONOKxwBU">https://www.youtube.com/playlist?list=PL4cUxeGkcC9jsz4LDYc6kv3ymONOKxwBU</a></div>
</li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=Q0a0594tOrc">NodeJS &amp; Express - Google OAuth2 using PassportJS</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=SBvmnHTQIPY&amp;t=352s">Node.js App From Scratch | Express, MongoDB &amp; Google OAuth</a></li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>It was a fun experience working with both Frontend Technologies and Backend Technologies, I look forward to building more Full Stack applications. So that's it, I wanted to share my experience building the application, hope it was a good read.</p>
<p>Also, If you'll like to contribute to the project, please do. I know there are a lot of bugs yet to be fixed, I might improve the project later on by making use of React or Next.js. </p>
<blockquote>
<p><strong>Lastly, don't forget to give the project a star ⭐, if you like the idea behind the project 😎 - <a target="_blank" href="https://github.com/jomefavourite/PlanDone">https://github.com/jomefavourite/PlanDone</a></strong></p>
</blockquote>
<p><strong>Thanks for Reading, do have a great day 👋</strong> </p>
]]></content:encoded></item><item><title><![CDATA[Let's build a Rich Text Editor using CKEditor5]]></title><description><![CDATA[Have you ever wondered how you're able to interact with the Google Docs application on the web and type in a bunch of text, add images and links and so on, well I have!
So in this article, we'll create a simple rich text editor, which allows you to t...]]></description><link>https://blog.favouritejome.dev/lets-build-a-rich-text-editor-using-ckeditor5</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-a-rich-text-editor-using-ckeditor5</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[Text Editors]]></category><category><![CDATA[editors]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Wed, 21 Jul 2021 12:36:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1627804307073/FXlcDa6vn.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever wondered how you're able to interact with the Google Docs application on the web and type in a bunch of text, add images and links and so on, well I have!</p>
<p>So in this article, we'll create a simple rich text editor, which allows you to type in text with different headings, supporting some markdown features, unfortunately not all but it's really cool what it can do.</p>
<p>Here's what we'll be building together, pretty basic but it's a rich text editor. Feel free to play around with it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/poPEJMz">https://codepen.io/jome-favourite/pen/poPEJMz</a></div>
<h2 id="heading-how-i-came-about-ckeditor">How I came about CKEditor?</h2>
<blockquote>
<p>If you don't care about the back story, <a class="post-section-overview" href="#rte">click here</a> to go to where we'll build the Rich Text Editor.</p>
</blockquote>
<p>While playing around with <code>textarea</code> element on the browser I found out that it accepts HTML elements, and they can be added to the DOM using JavaScript as HTML elements.</p>
<p>To try this out, type in any valid HTML element in the codepen textarea below, then click on the submit button.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/dyWpowR">https://codepen.io/jome-favourite/pen/dyWpowR</a></div>
<p>Hopefully, you've tried out the codepen above, If you notice whatever valid HTML element you input the textarea gets output just as an HTML element on the browser. That's really cool if you ask me.</p>
<p>So that's how the thought came, why do I have to type a statement like this <code>&lt;h1&gt;Hello&lt;/h1&gt;</code> every time into the textarea box. Isn't there an easier way to just click on a button which is meant for the heading <code>&lt;h1&gt;&lt;/h1&gt;</code> then type in some contents which will be represented like this <code>&lt;h1&gt;Contents are here&lt;/h1&gt;</code>?</p>
<p>Then I gave it a shot, tried my best to implement the functionality but failed, so I had to look for an alternative and that's how I found the CKEditor, which does exactly what I thought of.</p>
<p><span id="rte"></span></p>
<h2 id="heading-ckeditor">CKEditor</h2>
<p>The CKEditor is a smart rich text editor with collaborative editing. Well, we'll be building a really simple text editor, nothing too complicated but with lots of awesome features.</p>
<blockquote>
<p><a target="_blank" href="https://ckeditor.com/">Visit CKEditor website to find out more about its features</a></p>
</blockquote>
<p>For this tutorial, we will be using CKEditor 5, which is the latest version and also making use of the Classic editor which is one of the builds provided by CKEditor. </p>
<p>CKEditor provides 5 different builds which are essentially different ways to set up the rich text editor.</p>
<ul>
<li><a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">Classic editor</a></li>
<li><a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#inline-editor">Inline editor</a></li>
<li><a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#balloon-editor">Balloon editor</a></li>
<li><a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#balloon-block-editor">Balloon block editor</a></li>
<li><a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#document-editor">Document editor</a></li>
</ul>
<blockquote>
<p>Please I advise you to click on the different builds link above to explore.</p>
</blockquote>
<h2 id="heading-getting-started">Getting Started</h2>
<p>We'll be needing three files to work on this project, which are <code>index.html</code>, <code>style.css</code>, <code>main.js</code>. Firstly open up the <code>index.html</code> file.</p>
<h3 id="heading-html">HTML</h3>
<p>The first thing we'll need load the classic editor build with the CDN shown below in the <code>index.html</code> file at the <code>head</code> element. </p>
<pre><code class="lang-html">   <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
      ....
      <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.ckeditor.com/ckeditor5/28.0.0/classic/ckeditor.js"</span>&gt;</span><span class="xml">
   <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span></span>
</code></pre>
<p>Next off, we'll need a textarea and a button element mainly, followed by a div element where all the data from the editor will be added to as a card component. View the HTML file below: </p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Rich Text Editor<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.ckeditor.com/ckeditor5/28.0.0/classic/ckeditor.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Rich Text Editor<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"textarea"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"textarea"</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"10"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"output"</span>&gt;</span>
       <span class="hljs-comment">&lt;!-- What you type will appear here --&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Also, notice that there's an external script file named <code>main.js</code>. That's pretty much all there is for the HTML file. </p>
<p>If you're wondering, why are we using a textarea element, well it will get replaced to the Classical Editor once we load in the JavaScript file.</p>
<h3 id="heading-css">CSS</h3>
<p>The stylesheet is really basic, I'll leave you to go through it, but nothing much is going on.</p>
<pre><code><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Segoe UI'</span>, Tahoma, Geneva, Verdana, sans-serif;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">90%</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1000px</span>;
  <span class="hljs-attribute">margin</span>: auto;
}

<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">word-wrap</span>: break-word;
  <span class="hljs-attribute">overflow-wrap</span>: break-word;
}

<span class="hljs-selector-class">.card</span> {
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">10px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.274</span>);
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.1rem</span> <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">200px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">200px</span>;
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">word-break</span>: break-word;
  <span class="hljs-attribute">white-space</span>: normal;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">overflow</span>: auto;
}

<span class="hljs-selector-tag">button</span><span class="hljs-selector-attr">[id=<span class="hljs-string">'submit'</span>]</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5rem</span> <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">18px</span>;
}

<span class="hljs-selector-class">.ck-content</span> {
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">300px</span>;
}

<span class="hljs-selector-class">.output</span> {
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">3</span>, <span class="hljs-number">1</span>fr);
  <span class="hljs-attribute">grid-gap</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">2rem</span>;
}

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">480px</span>) {
  <span class="hljs-selector-class">.output</span> {
    <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-number">1</span>fr;
  }
}
</code></pre><h3 id="heading-javascript">JavaScript</h3>
<p>First, we select the appropriate elements we will need, such as the <code>div</code> element with the class name of <code>output</code> where all the cards containing whatever we type into the editor will be, the submit button, and the text area.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> output = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.output'</span>);
<span class="hljs-keyword">const</span> submitBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#submit'</span>);
<span class="hljs-keyword">const</span> textArea = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#textarea'</span>)
</code></pre>
<p>Next off, we need to call the method <code>ClassicEditor.create()</code> which takes in an argument which is the textarea element, which is referenced with the variable <code>textArea</code>.</p>
<pre><code class="lang-js"> ClassicEditor
        .create( textArea )
        .catch( <span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
            <span class="hljs-built_in">console</span>.error( error );
        } );
</code></pre>
<blockquote>
<p>The snippet below, is to catch any unforeseen errors that might occur, which means a promise is being returned by the method <code>ClassicEditor.create()</code></p>
<pre><code>.catch( <span class="hljs-function"><span class="hljs-keyword">error</span> =&gt; </span>{
     console.error( <span class="hljs-function"><span class="hljs-keyword">error</span> )</span>;
 } );
</code></pre></blockquote>
<p>Here's what should be shown on the browser if you've followed along so far, so it there's any issue please do traceback.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626473422862/UpmUa7xXU.png" alt="scrnli_7_16_2021_11-12-02 PM.png" /></p>
<p>Looking at the image above you'll notice there is an icon for adding images though it wouldn't work without some configuration and that adds more complexity to the simple Rich Text Editor, we are building.</p>
<blockquote>
<p>If you love to be able to add images to the CKEditor, please do read the docs here: <a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html">Custom image upload adapter</a></p>
</blockquote>
<p>So, what's best is to remove the feature completely and any other feature that isn't needed <em>(this is my preference, please feel free to play around the <a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/index.html">documentation</a> to learn more)</em> and make the Classic Editor as clean as possible. In other to do so, we'll need to change the default configurations that the CKEditor provides by added curly braces <code>{}</code> next to the <code>textArea</code>  variable.</p>
<pre><code class="lang-js">ClassicEditor.create(textArea, {
  <span class="hljs-attr">toolbar</span>: [
    <span class="hljs-string">'heading'</span>,
    <span class="hljs-string">'|'</span>,
    <span class="hljs-string">'bold'</span>,
    <span class="hljs-string">'italic'</span>,
    <span class="hljs-string">'link'</span>,
    <span class="hljs-string">'bulletedList'</span>,
    <span class="hljs-string">'numberedList'</span>,
    <span class="hljs-string">'blockQuote'</span>,
    <span class="hljs-string">'undo'</span>,
    <span class="hljs-string">'redo'</span>,
  ],
})
  .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
  });
</code></pre>
<p>So essential the <code>toolbar</code> property holds an array of all that should be shown by the editor and now you should have this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626866448601/qOwAuZktO.png" alt="scrnli_7_21_2021_12-22-41 PM.png" /></p>
<blockquote>
<p>I'll advise you to get your hands dirty with the code, try breaking things and not just only follow along, if you lose track just <kbd>Ctrl</kbd> + Z 😉</p>
</blockquote>
<p>Now we need to add the final functionality, which is to generate cards that contain what we type into the editor. To do this, we'll need to create a variable that would hold what is typed into the editor.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> textArea = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#textarea'</span>)

<span class="hljs-keyword">let</span> editor;

ClassicEditor.create(textArea, {...}
</code></pre>
<p>Then the <code>ClassicEditor.create()</code> method is to return a response data which will be captured by the <code>.then()</code> method. </p>
<pre><code class="lang-js">.
.
.

let editor;

ClassicEditor.create(textArea, {
  <span class="hljs-attr">toolbar</span>: [
    <span class="hljs-string">'heading'</span>,
    <span class="hljs-string">'|'</span>,
    <span class="hljs-string">'bold'</span>,
    <span class="hljs-string">'italic'</span>,
    <span class="hljs-string">'link'</span>,
    <span class="hljs-string">'bulletedList'</span>,
    <span class="hljs-string">'numberedList'</span>,
    <span class="hljs-string">'blockQuote'</span>,
    <span class="hljs-string">'undo'</span>,
    <span class="hljs-string">'redo'</span>,
  ],
})
  .then(<span class="hljs-function"><span class="hljs-params">newEditor</span> =&gt;</span> {
    <span class="hljs-comment">// notice the editor variable here is </span>
    <span class="hljs-comment">// holding the response daa from the editor</span>
    editor = newEditor;
  })
  .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
  });
</code></pre>
<p>By following the above snippet the variable <code>editor</code> will be holding an object with the contents that are typed into the editor.</p>
<p>Now, we need to work on the submit button, so when there's a click on the submit button a card will be generated with the contents from the editor.</p>
<pre><code class="lang-js">submitBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> editorData = editor.getData();

  <span class="hljs-keyword">if</span> (editorData) {
    output.innerHTML += <span class="hljs-string">`
      &lt;div class="card"&gt;
        <span class="hljs-subst">${editorData}</span>
      &lt;/div&gt;
    `</span>;

    editor.setData(<span class="hljs-string">''</span>);
  }
});
</code></pre>
<p>From the above snippet, the <code>submitBtn</code> has a listener for a click event, which then evokes the callback function. </p>
<p>Notice, <code>editor.getData()</code>. So <code>getData()</code> method is used to get the actual translated HTML elements from the editor, which is then held in the <code>editorData</code> variable.</p>
<p>Then, an <code>if</code> condition is next if <code>editorData</code> is true - meaning if it contains a string with contents, then the <code>output</code> innerHTML should be <code>editorData</code>. After this is done then we clear the contents in the editor setting the contents to an empty string with <code>editor.setData('')</code>.</p>
<p>Here's the complete codebase:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> output = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.output'</span>);
<span class="hljs-keyword">const</span> submitBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#submit'</span>);
<span class="hljs-keyword">const</span> textArea = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#textarea'</span>)

<span class="hljs-keyword">let</span> editor;

ClassicEditor.create(textArea, {
  <span class="hljs-attr">toolbar</span>: [
    <span class="hljs-string">'heading'</span>,
    <span class="hljs-string">'|'</span>,
    <span class="hljs-string">'bold'</span>,
    <span class="hljs-string">'italic'</span>,
    <span class="hljs-string">'link'</span>,
    <span class="hljs-string">'bulletedList'</span>,
    <span class="hljs-string">'numberedList'</span>,
    <span class="hljs-string">'blockQuote'</span>,
    <span class="hljs-string">'undo'</span>,
    <span class="hljs-string">'redo'</span>,
  ],
})
  .then(<span class="hljs-function"><span class="hljs-params">newEditor</span> =&gt;</span> {
    editor = newEditor;
  })
  .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
  });

submitBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> editorData = editor.getData();

  <span class="hljs-keyword">if</span> (editorData) {
    output.innerHTML += <span class="hljs-string">`
      &lt;div class="card"&gt;
        <span class="hljs-subst">${editorData}</span>
      &lt;/div&gt;
    `</span>;

    editor.setData(<span class="hljs-string">''</span>);
  }
});
</code></pre>
<blockquote>
<p>Note: If you've ever wondered why a string like an HTML element <code>"&lt;p&gt;Helllo&lt;/p&gt;"</code> can be added to another HTML element, just like we did above well its because <code>output</code> is a valid HTML element. So anything aside from an HTML element wouldn't be able to add a string HTML to the DOM.</p>
</blockquote>
<p>Get the code here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/jome-favourite/pen/poPEJMz">https://codepen.io/jome-favourite/pen/poPEJMz</a></div>
<p>Do checkout CKEditor documentation to know more about what they over: <a target="_blank" href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html">CKEditor Docs</a></p>
<p>Well, that is it, I hope you've learnt one or two things. I felt like sharing, hope you have a good day. <strong>Thanks for Reading</strong></p>
]]></content:encoded></item><item><title><![CDATA[My Experiences at Side Hustle Internship]]></title><description><![CDATA[Hello! 👋, In this article, I'll be sharing my experiences from Week 1 to Week 2 of the Side Hustle Internship, what I've learnt, the tasks given and so on.
But before I share how my experiences have been so far at Internship, I'll like to tell you w...]]></description><link>https://blog.favouritejome.dev/my-experiences-at-side-hustle-internship</link><guid isPermaLink="true">https://blog.favouritejome.dev/my-experiences-at-side-hustle-internship</guid><category><![CDATA[internships]]></category><category><![CDATA[projects]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sat, 03 Jul 2021 19:22:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1625339812356/CLQbeiodo.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello! 👋, In this article, I'll be sharing my experiences from Week 1 to Week 2 of the Side Hustle Internship, what I've learnt, the tasks given and so on.</p>
<p>But before I share how my experiences have been so far at Internship, I'll like to tell you what Side Hustle is all about.</p>
<p><strong>Side Hustle</strong> is a talent management platform that is aimed at reducing the rate of youth unemployment and poverty in Nigeria, by empowering youths (undergraduates, graduates and youth corp members) to learn from the best minds, execute their ideas and earn a living by offering their services to businesses.</p>
<blockquote>
<p>Note: Side Hustle Internship is done fully online.</p>
</blockquote>
<p><em>Founder of Sidehustle: <strong>Damilola Oyediran</strong></em></p>
<h2 id="my-experiences-at-the-internship">My Experiences at the Internship</h2>
<p>Honestly, it's been a refreshing experience for me. I've been able to go through things I already knew, things I had forgotten and learnt new things also.</p>
<p>The Internship has made me realise that just learning new technologies/tools is not enough, I should also be thinking about the monetary aspect of things too.</p>
<p>Because the end goal is to turn my learnings and passion into a way for me to meet my daily needs at the end by making money.</p>
<p>Also, I've been able to network with some fellow minded people, helping others with the little way I could and also reviewing others work.</p>
<h2 id="week-1">Week 1</h2>
<p>Here are the topics covered in Week 1.</p>
<ol>
<li>HTML</li>
<li>Git and Github
<br /><em>and lots more...</em></li>
</ol>
<h3 id="week-1-task">Week 1 Task</h3>
<p>The task was to create a tribute page, about anyone using up to 20 HTML tags.</p>
<p>Here's my solution to the task: <a target="_blank" href="https://codepen.io/jome-favourite/pen/YzZmqJx">task 1 solution</a></p>
<h2 id="week-2">Week 2</h2>
<p>The mentors went over CSS, how a website should be hosted, what and how things should be implemented, etc.</p>
<p>Here are the topics covered in Week 2.</p>
<ol>
<li>Introduction to CSS</li>
<li>How CSS works behind the scene (Cascade &amp; Specificity)</li>
<li>Responsive Design Strategies</li>
<li>Selecting breakpoints for media-queries</li>
<li>What is hosting/deployment</li>
<li>The different ways of hosting a website</li>
<li>Blogging</li>
<li>The importance of blogging and content writing</li>
</ol>
<h3 id="week-2-task">Week 2 Task</h3>
<p>Week 2 task is a challenge from <a target="_blank" href="https://frontendmentor.io">Frontendmentor</a>. Here's the challenge - <a target="_blank" href="https://www.frontendmentor.io/challenges/fylo-dark-theme-landing-page-5ca5f2d21e82137ec91a50fd">Fylo dark theme landing page</a>.</p>
<p>Actually, I had done this challenge already before but using Tailwindcss, but the task instruction was that no framework should be used but just plain CSS, so I had no other choice than to do it again.</p>
<p>Also, the main object for the task is to make use of CSS flex and CSS grid which was taught during Week 2.</p>
<h4 id="css-grid">CSS Grid</h4>
<p>For practising CSS grid, these are the sections I implemented Grid.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322383597/lS0Zxw88l.png" alt="scrnli_7_3_2021_3-26-58 PM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322372519/QJzQOMd4w.png" alt="scrnli_7_3_2021_3-27-15 PM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322364549/J-yHzsWSR.png" alt="scrnli_7_3_2021_3-27-35 PM.png" /></p>
<h4 id="css-flexbox">CSS Flexbox</h4>
<p>As for CSS flexbox, here are the sections I implemented the Flex functionality.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322738263/faMr8cUQP.png" alt="scrnli_7_3_2021_3-34-04 PM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322743991/b7eYUdL_H.png" alt="scrnli_7_3_2021_3-33-30 PM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322751337/nLO9KPN5S.png" alt="scrnli_7_3_2021_3-32-59 PM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625322759043/nT5gblN6e.png" alt="scrnli_7_3_2021_3-32-37 PM.png" /></p>
<h3 id="challenge-faced">Challenge faced</h3>
<p>While working on the task, I came across a challenge, a section of the design took me a while to wrap my head around it, but eventually, I was able to make it work.</p>
<p>Looking at the images below, you'll notice a curved background beneath the hero content, the wave like curved background is an SVG file, one for a desktop view and the other for a mobile view. So the problem was to display the appropriate curved background to the appropriate screen view without the background being off at a point.</p>
<blockquote>
<p>Desktop view
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625323677145/pdzp6Pcs3.png" alt="scrnli_7_3_2021_3-37-50 PM.png" /></p>
<p>Mobile view
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625324308239/4tesnIJwjI.png" alt="scrnli_7_3_2021_4-00-24 PM.png" /></p>
</blockquote>
<p>Remember I said earlier I had already done the challenge from <a target="_blank" href="https://frontendmentor.io">Frontendmentor</a> using Tailwindcss. While doing it then, I didn't have a hard switching between the two backgrounds at different screen views due to Tailwindcss utility classes.</p>
<p><strong>So how did I overcome this challenge without Tailwindcss?</strong></p>
<p>In other, for me to overcome the challenge, I made use of the <code>picture</code> element.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">picture</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">media</span>=<span class="hljs-string">"(min-width: 376px)"</span> <span class="hljs-attr">srcset</span>=<span class="hljs-string">"./images/bg-curvy-desktop.svg"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/bg-curvy-mobile.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"a navy blue background image"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">picture</span>&gt;</span>
</code></pre>
<p>From the snippet above, inside of the <code>picture</code> element, you'll notice the use of the <code>source</code> element and also the <code>img</code> element.</p>
<p>So the <code>picture</code> element holds <code>source</code> element and the <code>img</code> element, though you could have multiple <code>source</code> elements for different screen views.</p>
<p>The <code>source</code> element has the following attributes:</p>
<ul>
<li>srcset (required) - defines the URL of the image to show</li>
<li>media - accepts any valid media query that would normally be defined in a CSS</li>
<li>sizes - defines a single width descriptor, a single media query with width descriptor, or a comma-delimited list of media queries with a width descriptor</li>
<li>type - defines the MIME-type</li>
</ul>
<blockquote>
<p><em>The above information about the <code>source</code> was gotten from <a target="_blank" href>w3schools</a>, if you'll like to know more about the element do click on the link above.</em></p>
</blockquote>
<p>The <code>img</code> element is required as the last child tag of the <code>picture</code> declaration block.</p>
<p>The <code>img</code> element is used to provide backward compatibility for browsers that do not support the <code>picture</code> element, or if none of the <code>source</code> tags matched.</p>
<p>So that's how I overcame that challenge also with the use of some CSS tricks, which is available in the project submission on Github. <a target="_blank" href="https://github.com/jomefavourite/Sidehustle-task_fylo-dark-theme-landing-page">Click here to view the project code.</a></p>
<p>Live Demo to the Task: <a target="_blank" href="https://jome-sidehustle-task2.netlify.app/">jome-sidehustle-task2.netlify.app/</a></p>
<p>Github Link: <a target="_blank" href="https://github.com/jomefavourite/Sidehustle-task_fylo-dark-theme-landing-page">Sidehustle-task_fylo-dark-theme-landing-page</a></p>
<h2 id="conclusion">Conclusion</h2>
<p>It's been a fun and exciting program, meeting new people and also networking with others. I'm looking forward to the rest of the week and other tasks.</p>
<p>Thanks for reading, see you next time 😉</p>
]]></content:encoded></item><item><title><![CDATA[The World of Programming Paradigms]]></title><description><![CDATA[There are so many ways of writing programs, either by the programming language of choice or by the different features of a language. Understanding this fact will help you write more efficient programs if you ask me 😏.
So, in this article, I'll be sh...]]></description><link>https://blog.favouritejome.dev/the-world-of-programming-paradigms</link><guid isPermaLink="true">https://blog.favouritejome.dev/the-world-of-programming-paradigms</guid><category><![CDATA[General Programming]]></category><category><![CDATA[programming languages]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Fri, 28 May 2021 18:37:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622226774130/DonY-8vzQ.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are so many ways of writing programs, either by the programming language of choice or by the different features of a language. Understanding this fact will help you write more efficient programs if you ask me 😏.</p>
<p>So, in this article, I'll be sharing what are programming paradigms and mentioning a few of the paradigms we have out there in the world of programming and also reasons to use a particle paradigm.</p>
<hr />
<p>"The world of programming paradigms" - From the statement, the words can be broken down into three, which are <em>"World"</em>, <em>"Programming"</em> and <em>"Paradigms"</em>.</p>
<p>Let's know what these words mean:</p>
<ul>
<li><strong>World</strong>: can be thought of as a pictural view of the region/domain. </li>
<li><p><strong>Programming</strong>: From the word programming, there's another word - program, so what's a program.
<br /><br />
A <strong>program</strong> is a set of instructions used to solve/perform a specific task/problem. 
<br /><br />
With the word program being defined, now what's programming?
<br /><br />
<strong>Programming</strong> is simply the act of writing programs.</p>
</li>
<li><p><strong>Paradigms</strong>: are a set of concepts, thought patterns used in a domain/field.</p>
</li>
</ul>
<h2 id="heading-programming-paradigms">Programming Paradigms</h2>
<p>So, <strong>Programming Paradigm</strong> can be thought of like a way/style of writing programs. Also, it can be viewed as ways programs are classified based on their features.</p>
<p>There are so many programming paradigms out there, developed to solve problems and implemented in all programming languages like Java, C, JavaScript, etc. Due to the numerous paradigms, we are looking at just the two most common paradigms in this article.</p>
<blockquote>
<p>Note: Programming Paradigms doesn't refer to a particular programming language but rather the way of writing programs in that programming language.</p>
<p>Click here to view most of the <a target="_blank" href="https://en.wikipedia.org/wiki/Programming_paradigm">Programming paradigm</a> that exist.</p>
</blockquote>
<p>Before proceeding further, you should know that mostly all recently used programming languages are multi-paradigm, meaning they can be written using not just one but as many paradigms supported in the language.</p>
<p>There are two common programming paradigms, which are:</p>
<ul>
<li><strong>Imperative programming paradigm</strong></li>
<li><strong>Declarative programming paradigm</strong></li>
</ul>
<p>Both programming paradigms can further be divided as shown in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621524352354/hzvq76G5Y.png" alt="programming paradigms" /></p>
<blockquote>
<p>Note: There're more subdivisions to the Imperative programming paradigm and the Declarative programming paradigm, but we'll be concerned about the subdivisions shown in the image for this article.</p>
</blockquote>
<h3 id="heading-imperative-programming-paradigm">Imperative Programming Paradigm</h3>
<p>Firstly, what's the meaning of the word, Imperative?</p>
<p>Imperative could mean something vitally important, crucial or an act of giving an authoritative command.</p>
<p>So, therefore, In an Imperative Programming Paradigm, the order of steps is crucial, because the next step is mostly dependent on the previous step.</p>
<p>Here's an example in JavaScript to demonstrate my point:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>

sum+= <span class="hljs-number">1</span> <span class="hljs-comment">// sum = sum + 1</span>
sum+= <span class="hljs-number">2</span> <span class="hljs-comment">// sum = sum + 2</span>
sum+= <span class="hljs-number">3</span> <span class="hljs-comment">// sum = sum + 3</span>

<span class="hljs-built_in">console</span>.log(sum) <span class="hljs-comment">// 6</span>
</code></pre>
<p>From the snippet above, we notice that the variable <code>sum</code> is initialised with the value <code>0</code>. </p>
<p>Then the next couple of line is dependent on the current value of the variable <code>sum</code> which sums up to <code>6</code>.</p>
<p>From Imperative Programming Paradigm, other styles of writing programs were also derived and for this article, we'll be looking at two sub-modules which are <strong>Procedural programming</strong> and <strong>Object-Oriented programming</strong></p>
<h3 id="heading-procedural-programming">Procedural Programming</h3>
<p>Procedural programming is derived from the <strong>Imperative Programming Paradigm</strong>, which allows splitting of instructions into procedures also is concerned about the series of instructions to concur whereby each step relies on the previous step.</p>
<p>Procedural programming is much more like an iterative approach to solving a task/problem using loops (<code>for</code>, <code>while</code>) and <code>if</code> statements for control flow.</p>
<p>Here's an example to find the sum of numbers from 0 to 10, written in JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt;= <span class="hljs-number">10</span>; i++) {
  sum+= i 
}

<span class="hljs-built_in">console</span>.log(sum) <span class="hljs-comment">// 55</span>
</code></pre>
<p>From the snippet of code above, a <code>for</code> loop that iterates from 0 to 10 adding the previous <code>sum</code> variable with <code>i</code> and then the final output of the variable <code>sum</code> will be <code>55</code>.</p>
<p>Some major procedural programming language includes Fortran, ALGOL, BASIC and Pascal but more examples are found here <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Procedural_languages">List of programming languages by type - Procedural languages</a></p>
<blockquote>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Procedural_programming">Click here to know more about Procedural Programming</a></p>
</blockquote>
<h4 id="heading-why-learn-procedural-programming">Why learn Procedural Programming?</h4>
<ul>
<li>It's simple.</li>
<li>An easier way to keep track of program flow.</li>
<li>It has the ability to be strongly modular or structured.</li>
<li>Needs less memory: It's efficient and effective.</li>
</ul>
<h3 id="heading-object-oriented-programming-oop">Object-Oriented Programming (OOP)</h3>
<p>In Object-Oriented Programming, the concept of classes and objects are used. The paradigms specialise in modularity, breaking real-world entities into objects that can be reused.</p>
<p>Also, Object-Oriented Programming is based on the concept of objects where an object contains data/fields (attributes) and methods (behaviours).</p>
<p>Some key characteristics of the OOP are:</p>
<ul>
<li><strong>Class</strong>: A class is a blueprint or template of an object.</li>
<li><strong>Object</strong>: An object is an instantiation of a class.</li>
<li><strong>Abstraction</strong>: This is the process of hiding away complexity and showing only what is need.</li>
<li><strong>Inheritance</strong>: enables hierarchical relationships between classes.</li>
<li><strong>Encapsulation</strong>: is the concept that binds together the data
and methods that manipulate the data, and that keeps both safe from outside
interference and misuse.</li>
<li><strong>Polymorphism</strong>: this is the process by which variables, methods or objects can take multiple forms.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Person</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age, matricNo, level) {
    <span class="hljs-built_in">super</span>(name, age)

    <span class="hljs-built_in">this</span>.matricNo = matricNo;
    <span class="hljs-built_in">this</span>.level = level;
  }

  getStudenDetails() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is of age <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span>, 
his Matric Number is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.matricNo}</span> and his in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.level}</span>L`</span>
  }
}

<span class="hljs-keyword">const</span> student1 = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">'Favourite'</span>, <span class="hljs-number">18</span>, <span class="hljs-string">'RUN/CMP/18/7796'</span>, <span class="hljs-number">300</span>)
<span class="hljs-built_in">console</span>.log(student1.getStudenDetails())

<span class="hljs-comment">// outputs</span>
<span class="hljs-comment">// 'Favourite is of age 18, his Matric Number is RUN/CMP/18/7796 and his in 300L'</span>
</code></pre>
<p>From the snippet of code above, a class <code>Person</code> was first declared with its data/attributes as <code>name</code> and <code>age</code>. Also, the <code>Person</code> class is known as the Superclass because another class extends its properties.</p>
<p>Next off, another class was declared as <code>Student</code>, this class extends all the properties of the <code>Person</code> class because all students are also a person and this brings about inheritance.</p>
<h4 id="heading-why-uselearn-database-programming">Why use/learn Database programming</h4>
<ul>
<li>Reuse of code through Inheritance.</li>
<li>Flexibility through Polymorphism.</li>
<li>High security with the use of data hiding (Encapsulation) and Abstraction mechanisms.</li>
<li>An object-oriented programmer can stitch new software objects to make completely new programs.</li>
<li>For faster development of programs.</li>
</ul>
<h2 id="heading-declarative-programming-paradigm">Declarative Programming Paradigm</h2>
<p>Declarative programming is a style of building programs that express the logic of a computation without talking about its control flow.</p>
<p>From the word, <strong>Declarative</strong>; it means an announcement / a statement, so in this paradigm, the instructions that are to be carried out are declared meaning it doesn't need to be explicitly defined with how the instruction is to be meant done but just what is meant to be done.</p>
<p>Imagine being asked to draw a rectangle on a book, an imperative approach would state the various procedures like drawing two parallel lines on both axes while a declarative approach would just state the end goal and doesn't care about the process takes.</p>
<p>So the main differences are that imperative tells you <strong>how to do something</strong> and declarative tells you <strong>what to do</strong>.</p>
<p>Declarative Programming also has some programming languages beneath it, we'll be looking at <strong>Functional Programming</strong> and <strong>Database Programming</strong>.</p>
<h3 id="heading-functional-programming">Functional Programming</h3>
<p>The functional programming paradigm is rooted in using mathematical operation, it's a way of writing programs elegantly like you'll think of when thinking about a problem.</p>
<p>Also, Functional programming is the process of solving problems by composing pure functions, avoiding shared state, mutable data, and side effects. Functional programming is declarative rather than imperative, and application state flows through pure functions</p>
<p>Terms like: Recursion, Memoization, Pure Function, Composition are used along with  Functional Programming. </p>
<p>Let's say, a Fibonacci problem is to be solved, using a Functional approach makes the problem easier to solve and think about.</p>
<blockquote>
<p>Each Fibonacci number is defined as the sum of the previous two Fibonacci numbers, so fibonacci(n) = fibonacci(n-1) + fibonacci(n-2). By convention, the first two numbers are fixed: fibonacci(0) = 0 and fibonacci(1) = 1.</p>
</blockquote>
<p>Here's the Functional approach of solving a Fibonacci problem using JavaScript.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">recursiveFibonacci</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> ( n &lt;== <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
  <span class="hljs-keyword">if</span> ( n === <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>

  <span class="hljs-keyword">return</span> recursiveFibonacci(n<span class="hljs-number">-1</span>) + recursiveFibonacci(n<span class="hljs-number">-2</span>)
}

recursiveFibonacci(<span class="hljs-number">6</span>) <span class="hljs-comment">// 8</span>
</code></pre>
<blockquote>
<p>Note, there some caveat to Functional Programmings, like the Memory Stackoverflow, but there are also solutions to this caveat like <a target="_blank" href="https://youtu.be/-PX0BV9hGZY">Tail Call Optimation</a></p>
</blockquote>
<p>Read this wonder article to know more about Functional Programming: <a target="_blank" href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0#:~:text=Functional%20programming%20(often%20abbreviated%20FP,state%20flows%20through%20pure%20functions.">Master the JavaScript Interview: What is Functional Programming?</a></p>
<h4 id="heading-why-uselearning-functional-programming">Why use/learning Functional programming?</h4>
<ul>
<li>Functions can be coded quickly and easily.</li>
<li>Unit testing is easier.</li>
<li>Debugging is easier.</li>
<li>Overall application is less complex since functions are pretty straightforward.</li>
</ul>
<h3 id="heading-database-programming">Database Programming</h3>
<p>A database is an organized collection of structured information, or data,
typically stored electronically in a computer system. A database is usually
controlled by a database management system (DBMS).</p>
<p>To process the data and querying them, databases use tables. Data can then be
easily accessed, managed, modified, updated, controlled and organized.</p>
<p>Most databases use Structured Query Language (SQL) for writing and querying
data.</p>
<p>There're three major parts to Database Programming: </p>
<ul>
<li>Relational Database</li>
<li>NoSQL Database</li>
<li>Cloud Database</li>
</ul>
<blockquote>
<p>Read this article to know more about Databases: <a target="_blank" href="https://www.edureka.co/blog/what-is-a-database/">What is a Database? - edureka</a></p>
</blockquote>
<p>Below, are simple declaration and schema declaration on what should be in a data show be in a database.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">DATABASE</span> Students;

<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> ComputerScienceStudent (
      MatricID <span class="hljs-built_in">int</span>,
      LastName <span class="hljs-built_in">varchar</span>(<span class="hljs-number">25</span>),
      FirstName <span class="hljs-built_in">varchar</span>(<span class="hljs-number">25</span>)
);
</code></pre>
<h4 id="heading-why-learnuse-database-programming">Why learn/use Database Programming</h4>
<ul>
<li>When you need to handle massive amount of data.</li>
<li>With the help of built-in functionalities in a database, we can easily validate data coming into the database.</li>
<li>Easy to update data: Data Manipulation Languages (DML) such as SQL are used to
update data in a database easily.</li>
<li>Data integrity: With the help of built-in validity checks, we can ensure the consistency of data.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I'm pretty sure in some ways, directly or indirectly you've written programs using the combinations of all the Programming paradigms mentioned above, probably without your knowledge. Well, know you know some of the most used programming paradigms and reasons to use them.</p>
<p>I hope you found the article useful, thanks for reading!</p>
<h2 id="heading-references">References</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/what-exactly-is-a-programming-paradigm/">What exactly is a programming paradigm? - Freecodecamp</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/List_of_programming_languages_by_type">List of programming languages by type - Wikipedia</a></li>
<li><a target="_blank" href="https://hackr.io/blog/programming-paradigms">Programming Paradigms: A must know for all Programmers - hackr.io</a></li>
<li><a target="_blank" href="https://java-programming.mooc.fi/part-7/1-programming-paradigms">Programming paradigms - java-programming.mooc.fi</a></li>
<li><a target="_blank" href="https://www.edureka.co/blog/what-is-a-database/">What is a Database? Definition, Types and Components</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Let's build a Multi-coloured Card Component using Sass/SCSS]]></title><description><![CDATA[Hello 👋, In this article, we'll be building a multi-coloured card component with the help of Sass (Syntactically Awesome Style Sheets) awesome features. This article is geared towards implementing some complex Sass feature that may/may not be known ...]]></description><link>https://blog.favouritejome.dev/lets-build-a-multi-coloured-card-component-using-sass</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-a-multi-coloured-card-component-using-sass</guid><category><![CDATA[Sass]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sat, 15 May 2021 10:29:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1621047272818/_uDwpK0f-.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello 👋, In this article, we'll be building a multi-coloured card component with the help of <strong>Sass</strong> (Syntactically Awesome Style Sheets) awesome features. This article is geared towards implementing some complex <strong>Sass</strong> feature that may/may not be known to you if you just started learning about Sass. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621036447156/JPX0WZ2A4.png" alt="scrnli_5_15_2021_12-53-50 AM.png" /></p>
<h2 id="prerequisite">Prerequisite</h2>
<ul>
<li>Basic knowledge of HTML</li>
<li>Basic Knowledge of Sass/SCSS</li>
<li>Basic knowledge of Terminal</li>
</ul>
<h2 id="getting-started">Getting Started</h2>
<p>To get started, we'll need a folder created and opened on your favourite IDE (Integrated Development Environment), mine is VSCode with a file <code>index.html</code> also created.</p>
<p>Next off, run the command below into the terminal of your choice to install <strong>Sass</strong> globally on the PC. </p>
<pre><code><span class="hljs-built_in">npm</span> install -g sass
</code></pre><blockquote>
<p>If you've installed <strong>Sass</strong> globally once before now there's no need to run the command again.</p>
</blockquote>
<p>Moving on, we'll need Sass installed on the current directory/folder we're working on as a dependencies. Please make sure you run the command below on the project directory/folder.</p>
<pre><code><span class="hljs-built_in">npm</span> install sass
</code></pre><p>By running the command above, we should have a folder created <code>node-modules</code> and a <code>package-lock.json</code> file.</p>
<p>Now, we need to run a script, which watches for changes while using Sass. In other to do so, we'll need to run another command on the terminal.</p>
<pre><code>npm init <span class="hljs-comment">--y</span>
</code></pre><p>By running the command above, a <code>package.json</code> file will be created. Let's open the file and then navigate to the <code>"scripts"</code> key pair, where the default values there will be changed to the command below:</p>
<pre><code><span class="hljs-string">"script"</span>: {
  <span class="hljs-string">"start"</span>: <span class="hljs-string">"sass scss:css --watch"</span>
}
</code></pre><p>The command above watches all the Sass stylesheet file in the <strong>scss</strong> folder, (which we haven't created yet) then compiles the Sass stylesheet file into a CSS stylesheet in an auto-generated css folder. That's basically what the command does.</p>
<p>That's all for the setup, so now let's dive right into coding.</p>
<h3 id="html">HTML</h3>
<p>Let's open the <code>index.html</code> file created and then copy-paste the code below into the file.</p>
<blockquote>
<p>Don't worry we'll go over the index.html file 😏</p>
</blockquote>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- index.html --&gt;</span>

<span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Multi-Coloured Card Components<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"./css/style.css"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Multi-coloured Cards with SCSS<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Suscipit
            facere illo iusto debitis aperiam labore obcaecati harum dicta
            nesciunt quae.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>From the HTML snippet above, we can see nothing much is going on. But notice there's a repeated element with the class attribute <code>.card</code> having nested <code>h2</code> and <code>p</code> elements. That's the component that will be multi-coloured with the help of Sass.</p>
<p>Also, notice there's a link to CSS stylesheet from the css folder, which will be created soon.</p>
<p><code>&lt;link rel="stylesheet" href="./css/style.css" /&gt;</code></p>
<p>That's all for the HTML file, let's move on to the next section.</p>
<h3 id="sassscss-syntactically-awesome-style-sheets">Sass/SCSS (Syntactically Awesome Style Sheets)</h3>
<p>Here's where the main functionalities will be added but take note this article isn't a beginner fundamental of Sass, so I'll suggest you read this article <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">Write CSS with Superpowers Using Sass.</a> which explains the fundamentals of Sass.</p>
<blockquote>
<p>If you're wondering what's with Sass and SCSS (which are two different extensions), I'll suggest you read the article above.</p>
</blockquote>
<p>So now, let's create a folder named <strong>scss</strong> and in it, three files as shown below.</p>
<pre><code class="lang-directory">scss
|-- _utilities.scss
|-- _card.scss
|-- style.scss
</code></pre>
<p>Notice that both <code>_utilities.scss</code> and <code>_card.scss</code> files have a prefix <code>_</code> attached to the file names. This signifies that's it a partial file in <strong>Sass</strong> which wouldn't be compiled until used in the main <code>style.scss</code> file.</p>
<blockquote>
<p>If you don't understand anything mentioned above, once again I'll suggest you read <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">this article</a></p>
</blockquote>
<p>Since the <code>scss</code> folder has been created, its time to watch for changes in the <code>scss</code> folder. To do that run the command below:</p>
<pre><code class="lang-directory">npm start
</code></pre>
<p>Now, we should have an additional folder created - <code>css</code> folder with two files, <code>style.css</code> and <code>style.css.map</code> and the setup should look the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621073738050/FiKYmEjw0.png" alt="preview.png" /></p>
<p>Let's open the <code>style.scss</code> file and then include the code below in the file.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* style.scss */</span>

<span class="hljs-keyword">@use</span> <span class="hljs-string">'./card'</span>;
</code></pre>
<p>From the code above, we making use of the <code>@use</code> rule, which loads the contents from <code>_card.scss</code> file. Notice there's no need to specify the path with the extension, Sass is smart enough to know the extension. All that's needed is the path name to the stylesheet to be loaded.</p>
<p>For now, the <code>_card.scss</code> file is empty, but don't worry we'll be fixing that soon,</p>
<blockquote>
<p>Read more on the <a target="_blank" href="https://sass-lang.com/documentation/at-rules/use">@use rule here</a></p>
</blockquote>
<p>The <code>_utilities.scss</code> file is where we'll be including some Sass features we'll need to implement a multi-coloured card component.</p>
<p>Firstly, we'll need to create a Map, which is a Sass feature and not available in CSS.</p>
<p>Maps in Sass hold pairs of keys and values and make it easy to look up a value by its corresponding key. </p>
<p>You can think of a Map in Sass like an object in JavaScript but it's symbolized with the parentheses symbol <code>()</code>.</p>
<p>Below is an example of a Map in Sass named <code>$cardBackground</code>:</p>
<pre><code class="lang-css">$<span class="hljs-selector-tag">cardBackground</span>: (
  '1': <span class="hljs-selector-tag">rgb</span>(168, 4, 4),
  '2': <span class="hljs-selector-tag">rgb</span>(30, 30, 155),
  '3': <span class="hljs-selector-tag">black</span>,
  '4': <span class="hljs-selector-tag">gold</span>,
  '5': <span class="hljs-selector-tag">indigo</span>,
  '6': <span class="hljs-selector-tag">rgb</span>(192, 4, 104)
);
</code></pre>
<blockquote>
<p>To declare a variable in Sass, the symbol <code>$</code> must be included, whereas with plain CSS we use <code>--</code>.</p>
</blockquote>
<p>From the snippet above, the incremented numbering are the keys (<code>1, 2, 3, 4, 5, 6</code>) then the values are the colours on the left. In this case, we are using the Map to storing colours that will be used in the card components. </p>
<blockquote>
<p>Read more about Sass Maps from <a target="_blank" href="https://sass-lang.com/documentation/values/maps">Sass Documentation</a></p>
</blockquote>
<p>Now, that a Map has been created where the colours will be stored, we also need a way to detect the lightness of colours listed in the Map, to determine what colour should the text be based on the background colour. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621032266611/cBeC_WQ7H.png" alt="scrnli_5_14_2021_11-45-33 PM.png" /></p>
<blockquote>
<p>From the image above, it's noticeable that the card component with a background Yellow has its text colour as Black whereas the other card components text colour is white.</p>
</blockquote>
<p>I know right, that seems unreal. Well, that's where another Sass feature comes into play, which is a colour function - <code>lightness(colour-name)</code>.  </p>
<p>To access the colour function <code>lightness(colour-name)</code>, we'll need a built-in module in Sass, which is the <code>color</code> module. Then, to import the module, we'll make use of the <code>@use</code> rule:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@use</span> <span class="hljs-string">"sass:color"</span>;
</code></pre>
<blockquote>
<p>Note, the <code>@use "sass:color"</code> rule must be called before it's being used. Preferably, placed at the top of the <code>_utitlities.scss</code> file.</p>
<p>The colour function - <code>lightness()</code> ranges from <code>0%</code> to <code>100%</code>.</p>
<p>Read more on the <a target="_blank" href="https://sass-lang.com/documentation/at-rules/use">@use rule here</a></p>
</blockquote>
<p>Since, we'll have to use a condition to determine the lightness of the background colour, it's essential we have a function. Yes! Sass also actual functions like other programming languages 😉.</p>
<p>Now, lets go over the function below:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* _utilities.scss */</span>

<span class="hljs-comment">/* Set text color based on bg */</span>
<span class="hljs-keyword">@function</span> set-text-color($color) {
  <span class="hljs-keyword">@if</span> (color.lightness($color) &gt; <span class="hljs-number">40%</span>) {
    <span class="hljs-keyword">@return</span> #<span class="hljs-number">000</span>;
  } <span class="hljs-keyword">@else</span> {
    <span class="hljs-keyword">@return</span> #fff;
  }
}
</code></pre>
<p>Looking at the code above, firstly, we notice the use of the <code>@</code> rule - (At's rule), which is used to declare a function is Sass. The name of the function is <code>set-text-color</code> and the function has a parameter <code>($color)</code> - <em>Notice the <code>$</code> prefix, indicating that it's a variable.</em></p>
<p>On the next line, an if statement is declared, also with the <code>@</code> rule, checking if the <code>color.lightness($color)  &gt; 40%</code>. If the condition is true, then colour black will be returned - <code>@return #000;</code> else colour white will be returned - <code>@return #fff;</code>.</p>
<blockquote>
<p>Read more about <a target="_blank" href="https://sass-lang.com/documentation/at-rules/function"><code>@function</code> rule here</a></p>
</blockquote>
<p>Okay, so that's all for the text colour functionality, so now we need to set the background colour and also call the Sass function we've declared with the same background colour. To implement this, we'll need another Sass feature named <strong>Mixins</strong>.</p>
<p>Mixins allow us to define styles that can be re-used throughout your stylesheet, basically and it's similar to Sass functions but doesn't use the <code>@return</code> rule.</p>
<p>Let's go over the code:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Set background &amp; text color */</span>
<span class="hljs-keyword">@mixin</span> set-background($color) {
  <span class="hljs-selector-tag">background-color</span>: $<span class="hljs-selector-tag">color</span>;
  <span class="hljs-selector-tag">color</span>: <span class="hljs-selector-tag">set-text-color</span>($<span class="hljs-selector-tag">color</span>);
}
</code></pre>
<p>Firstly, the mixin is declared using the <code>@mixin</code> rule with its name as <code>set-background</code> and expecting a parameter - <code>$color</code> when used. </p>
<p>Inside the mixin declaration, the <code>background-color</code>property is assigned the value <code>$color</code> which is the parameter variable. Then the <code>color</code> property has its value as the invocation of the Sass function which was initialised earlier - <code>set-text-color($color)</code> with the <code>$color</code> variable passed as the function argument.</p>
<blockquote>
<p>If this section isn't clear, please feel free to ask in the comment</p>
<p>Read more about the <a target="_blank" href="https://sass-lang.com/documentation/at-rules/mixin">@mixin rule here</a></p>
</blockquote>
<p>By now, our <code>_utilities.scss</code> stylesheet should look like this:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* _utilities.scss */</span>

<span class="hljs-keyword">@use</span> <span class="hljs-string">"sass:color"</span>;

$<span class="hljs-selector-tag">cardBackground</span>: (
  '1': <span class="hljs-selector-tag">rgb</span>(168, 4, 4),
  '2': <span class="hljs-selector-tag">rgb</span>(30, 30, 155),
  '3': <span class="hljs-selector-tag">black</span>,
  '4': <span class="hljs-selector-tag">gold</span>,
  '5': <span class="hljs-selector-tag">indigo</span>,
  '6': <span class="hljs-selector-tag">rgb</span>(192, 4, 104)
);

<span class="hljs-comment">/* Set text color based on bg */</span>
<span class="hljs-keyword">@function</span> set-text-color($color) {
  <span class="hljs-keyword">@if</span> (color.lightness($color) &gt; <span class="hljs-number">40%</span>) {
    <span class="hljs-keyword">@return</span> #<span class="hljs-number">000</span>;
  } <span class="hljs-keyword">@else</span> {
    <span class="hljs-keyword">@return</span> #fff;
  }
}

<span class="hljs-comment">/* Set background &amp; text color */</span>
<span class="hljs-keyword">@mixin</span> set-background($color) {
  <span class="hljs-selector-tag">background-color</span>: $<span class="hljs-selector-tag">color</span>;
  <span class="hljs-selector-tag">color</span>: <span class="hljs-selector-tag">set-text-color</span>($<span class="hljs-selector-tag">color</span>);
}
</code></pre>
<p>So that's all for the <code>_utilities.scss</code> stylesheet file, now it's time we use the utilities created in the <code>_card.scss</code> file. So open up the <code>_card.scss</code> file.</p>
<p>Firstly, we'll need to import the <code>_utilities.scss</code> file with a namespace into the <code>_card.scss</code> file. </p>
<blockquote>
<p>Namespace is a name given to a module to access variables, functions, and mixins that has been declared in the module.</p>
<p><code>util</code> is the namespace name from the code below:</p>
</blockquote>
<pre><code class="lang-css"><span class="hljs-comment">/*  _card.scss */</span>

<span class="hljs-keyword">@use</span> <span class="hljs-string">'./utilities'</span> as util;
</code></pre>
<blockquote>
<p>Read more about <a target="_blank" href="https://sass-lang.com/documentation/at-rules/use">@use rule here</a></p>
</blockquote>
<p>Next off, we need a way to loop through the several <code>div</code> elements with the class name <code>card</code>, applying the several colours listed in the Sass Map. To implement this, we'll need yet again, another Sass feature which is the <code>@each</code> rule.</p>
<blockquote>
<p>The @each rule makes it easy to emit styles or evaluate code for each element of a list or each pair in a map. It’s great for repetitive styles that only have a few variations between them.</p>
<p><a target="_blank" href="https://sass-lang.com/documentation/at-rules/control/each"><em> - From Sass Documentation</em></a></p>
</blockquote>
<p>The syntax goes like this for looping through a Map:</p>
<p><code>@each &lt;key variable&gt;, &lt;value variable&gt; in &lt;map varible&gt;</code></p>
<p>Let's go the code below: </p>
<pre><code class="lang-css"><span class="hljs-comment">/*  _card.scss */</span>

<span class="hljs-keyword">@each</span> $key, $value in util.$cardBackground {
  <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(</span>#{$key}) {
    @include util.set-background($value);
  }

  ...
}
</code></pre>
<p>Firstly, the @each rule is declared with two Sass variable <code>$key</code>, <code>$value</code> followed by <code>in</code>, then <code>util.$cardBackground</code>. Notice that the variable <code>$cardBackground</code> which is the Map isn't declared in the <code>_card.scss</code> file but is being imported using the namespace name <code>util</code>.</p>
<p>Then, for each <code>.card</code> selector, we loop through it by the pseudo-class <code>:nth-of-type(n)</code> which takes in an argument. The argument of the card pseudo-class should be each key in the map, whereby it like this:</p>
<pre><code> <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type</span>(#{<span class="hljs-variable">$key</span>})  {...}
</code></pre><p>You might wonder, why not <code>.card:nth-of-type($key)</code> and what's with the <code>#{}</code> symbols. Well, we can't use Sass variables on CSS selectors directly except we interpolate it.</p>
<p>Interpolation in Sass is a way of embedding results of Sass expressions, using the symbols <code>#{}</code>. So, that's why the selector has to be written this way: <code>.card:nth-of-type(#{$key})  {...}</code></p>
<blockquote>
<p>Read more on <a target="_blank" href="https://sass-lang.com/documentation/interpolation">Interpolation here</a></p>
</blockquote>
<p>Next off, we need to include the Mixin we once created in the <code>_utilities.scss</code> file, which set background colours. To do this, we need to make use of the <code>@include</code> rule which only works with Mixins. Also, the mixin - <code>set-background($value)</code> is accessed from the namespace <code>util</code>.</p>
<pre><code> <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type</span>(#{<span class="hljs-variable">$key</span>}) {
    <span class="hljs-keyword">@include</span> util.set-background(<span class="hljs-variable">$value</span>);
  }
</code></pre><p>Notice, the mixin - <code>set-background($value)</code> has the <code>$value</code> variable as its argument which are the values in the Map - <code>$cardBackground</code>.</p>
<p>By now, the card components should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621043211095/MZQuk66pU.png" alt="scrnli_5_15_2021_2-48-12 AM.png" /></p>
<p>But it looks too plain, isn't it? To make card components have a not so plain background 😂, we're going to add the code below to the <code>@each</code> rule.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@each</span> $key, $value in util.$cardBackground {
  ...

  <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(</span>#{$key})<span class="hljs-selector-pseudo">::before</span> {
    <span class="hljs-attribute">background</span>: color.<span class="hljs-built_in">adjust</span>($value, $blackness: <span class="hljs-number">10%</span>);
  }
}
</code></pre>
<p>Firstly, we have <code>.card:nth-of-type(#{$key})::before</code> as the selector with the pseudo element <code>::before</code>, then the background property has it value as <code>color.adjust($value, $blackness: 10%)</code>.</p>
<p>Looking at the value of the background property, it shows that <code>color</code> is used, so it needs to be imported <code>@use "sass:color"</code>, which then gives access to the colour function - <code>adust()</code>.</p>
<p>The <code>adjust()</code> function takes in lots of argument, but for this use case, it takes only two arguments. The first argument is the colour that should be adjusted which is <code>$value</code> variable from the Map and then the second argument is <code>$blackness: 10%</code> which means darken the colour in the <code>$value</code> variable by <code>10%</code>.</p>
<blockquote>
<p>Read more on the <a target="_blank" href="https://sass-lang.com/documentation/at-rules/control/each">@each rule here</a></p>
</blockquote>
<p>Here's the preview of how it should look like now:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621045034371/LVq_zbEfY.png" alt="scrnli_5_15_2021_3-18-17 AM.png" /></p>
<p>Okay then, let's see the translation for the <code>@each</code> rule in plain CSS:</p>
<pre><code><span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(1)</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#a80404</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(1)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#8f0404</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(2)</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#1e1e9b</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(2)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#1e1e82</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(3)</span> {
  <span class="hljs-attribute">background-color</span>: black;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(3)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: black;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(4)</span> {
  <span class="hljs-attribute">background-color</span>: gold;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(4)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#e6c200</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(5)</span> {
  <span class="hljs-attribute">background-color</span>: indigo;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(5)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#3c0069</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(6)</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#c00468</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(6)</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#a7045a</span>;
}
</code></pre><p>We can see, that each <code>.card</code> selector has a unique background colour and text colour. So, if you'll ever need more than 6 card component, just add more colour to the Map in the <code>_utilities.scss</code> file and Sass does its magic.</p>
<p>Here's the complete <code>_card.scss</code> stylesheet</p>
<pre><code class="lang-css"><span class="hljs-comment">/*  _card.scss */</span>

<span class="hljs-keyword">@use</span> <span class="hljs-string">'./utilities'</span> as util;
<span class="hljs-keyword">@use</span> <span class="hljs-string">'sass:color'</span>;

* {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Roboto'</span>;
}

<span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2em</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0.67em</span> <span class="hljs-number">0</span>;
  <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-class">.container</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">90%</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">700px</span>;
  <span class="hljs-attribute">margin</span>: auto;
}

<span class="hljs-selector-class">.container</span> &gt; * + * {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">1rem</span>;
}

<span class="hljs-selector-class">.card</span> {
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">500px</span>;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">::before</span> {
  <span class="hljs-attribute">content</span>: <span class="hljs-string">''</span>;
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">10px</span>;
}

<span class="hljs-keyword">@each</span> $key, $value in util.$cardBackground {
  <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(</span>#{$key}) {
    @include util.set-background($value);
  }

  <span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:nth-of-type(</span>#{$key})<span class="hljs-selector-pseudo">::before</span> {
    <span class="hljs-attribute">background</span>: color.<span class="hljs-built_in">adjust</span>($value, $blackness: <span class="hljs-number">10%</span>);
  }
}

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">min-width:</span> <span class="hljs-number">500px</span>) {
  <span class="hljs-selector-class">.container</span> {
    <span class="hljs-attribute">display</span>: grid;
    <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr;
    <span class="hljs-attribute">gap</span>: <span class="hljs-number">1rem</span>;

    &gt; * + * {
      <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">0</span>;
    }
  }
}
</code></pre>
<h2 id="resources">Resources</h2>
<ul>
<li><a target="_blank" href="https://sass-lang.com/documentation">Sass Documentation</a></li>
<li><a target="_blank" href="https://www.sassmeister.com/">Sass Playground</a></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>To make this project even more interesting, you could use JavaScript to add input fields, to generate more card components which will then have their individual background colours, but then you'll have to add more colours to the Sass Map. </p>
<p>I hope the article was helpful in a way, Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[Let's build a Custom Search Filter using JavaScript]]></title><description><![CDATA[A while back, I had to build a search filtering functionality for a class project I was working on which took a while to figure out so, in this article, we'll build it together. It simply filters a list of data/information. For this article, the list...]]></description><link>https://blog.favouritejome.dev/lets-build-a-custom-search-filter-using-javascript</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-a-custom-search-filter-using-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Fri, 07 May 2021 09:30:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1620379784275/72z-o_2Gx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A while back, I had to build a search filtering functionality for a class project I was working on which took a while to figure out so, in this article, we'll build it together. It simply filters a list of data/information. For this article, the list will be represented as todos we'll have to do, hopefully 😀. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1620054704072/TIDU2iDPP.gif" alt="17811fd5-37ed-43c6-9183-064f08a392c3.gif" /></p>
<p><a target="_blank" href="https://jomefavourite.github.io/Filter_Functionality_Javascript/">Demo</a></p>
<p><a target="_blank" href="https://github.com/jomefavourite/Filter_Functionality_Javascript">Code here</a></p>
<h3 id="heading-getting-started">Getting Started</h3>
<p>For us to get started we'll need to create a folder, named as anything we like but for the project seek we could name the folder <strong>filter_functionality</strong>. In this folder, we'll need three files which will be <code>index.html</code>, <code>style.css</code>, <code>main.js</code>.</p>
<h3 id="heading-html">HTML</h3>
<p>The HTML file is going to be basic, nothing complicated. We'll just need an input element to enter our search then an unordered list of todos.</p>
<p>Also, the HTML file should be linked to both the CSS file and the JS file.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Filter Functionality<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"search"</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"search"</span>
          <span class="hljs-attr">id</span>=<span class="hljs-string">"search"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search for todos"</span>
          <span class="hljs-attr">autocomplete</span>=<span class="hljs-string">"off"</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Finish my assignment<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Complete the project on Time<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Contribute to the several Open Source Communities I'm in<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Playing my favourite songs<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Watching my favourite series<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"notFound"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>No Todo Found<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-css-file">CSS FIle</h3>
<p>Also, the CSS style sheet isn't complicated, just some little styling to make things fancy 😎.</p>
<pre><code class="lang-CSS">* {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Open Sans'</span>;
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.082</span>);
}

<span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">80%</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">500px</span>;
  <span class="hljs-attribute">margin</span>: auto;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">10px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.274</span>);
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">'search'</span>]</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">2rem</span>;
}

<span class="hljs-selector-tag">ul</span> <span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">list-style</span>: none;
  <span class="hljs-attribute">border-left</span>: <span class="hljs-number">2px</span> solid black;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5rem</span>;
}

<span class="hljs-selector-tag">li</span> + <span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">1rem</span>;
}

<span class="hljs-selector-id">#notFound</span> {
  <span class="hljs-attribute">display</span>: none;
}
</code></pre>
<blockquote>
<p>Notice, <code>#notFound</code> selector has <code>display: none</code> as its declaration because we only want it visible when no todo is found. More on that in the JavaScript section.</p>
</blockquote>
<h3 id="heading-javascript">JavaScript</h3>
<p>The JavaScript file is where all our main functionality will be applied, as expected 😉.</p>
<p>Let's go over the code snippet below and we'll work through the code step by step.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> search = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#search'</span>);
<span class="hljs-keyword">const</span> todos = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'ul li'</span>);
<span class="hljs-keyword">const</span> notFound = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#notFound'</span>);

search.addEventListener(<span class="hljs-string">'keyup'</span>, filterFunctionality);
</code></pre>
<ul>
<li>First thing first, we select all the elements we'll be needing from the DOM (Document Object Model). What will be selected are the input element, all the list elements and the element with the <code>id</code> of <strong><em>notFound</em></strong> as seen from <strong>line 1 - 3.</strong>
<br /><blockquote>
<p><code>const todos = document.querySelectorAll('ul li')</code>
<br />
<br />
Notice from the code above, we are selecting all the list elements which return a Nodelist object.
<br />
<br />
A NodeList object is a list (collection) of nodes extracted from a document.
<br />
<br />
Read more about the Nodelist Object here: <a target="_blank" href="https://www.w3schools.com/js/js_htmldom_nodelist.asp#:~:text=A%20NodeList%20is%20a%20collection, in%20the%20list%20(collection">w3schools - Nodelist Object</a></p>
</blockquote>
</li>
</ul>
<ul>
<li>The input element <code>search</code> has an event listener attached to it with the type of event as <code>keyup</code> and a callback function\listener named <code>filterFunctionality</code></li>
</ul>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">filterFunctionality</span>(<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">let</span> searching = e.target.value.toLowerCase();

  <span class="hljs-comment">// Filters the todo</span>
  [...todos].forEach(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
    <span class="hljs-keyword">let</span> todoContent = todo.textContent;
    <span class="hljs-keyword">if</span> (todoContent.toLowerCase().includes(searching)) {
      todo.style.display = <span class="hljs-string">'block'</span>;
    } <span class="hljs-keyword">else</span> {
      todo.style.display = <span class="hljs-string">'none'</span>;
    }
  });

  <span class="hljs-comment">// Displays No Todo Found</span>
  <span class="hljs-keyword">let</span> result = [...todos].every(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> todo.style.display === <span class="hljs-string">'none'</span>;
  });

  result === <span class="hljs-literal">true</span>
    ? (notFound.style.display = <span class="hljs-string">'block'</span>)
    : (notFound.style.display = <span class="hljs-string">'none'</span>);

}
</code></pre>
<ul>
<li>The function <code>filterFunctionality</code> takes in a parameter <code>e</code> which is the event object and implicitly passed to the function.</li>
</ul>
<blockquote>
<p>The Event Object is created once there's an event for example when a button is clicked.</p>
<p>Read more about the [Event Object here]</p>
<ul>
<li><a target="_blank" href="https://www.w3schools.com/jsref/obj_event.asp">w3schools - The Event Object</a> </li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Event">MDN - Event</a></li>
</ul>
</blockquote>
<ul>
<li>A variable is declared <code>searching</code> with the value as <code>e.target.value.toLowerCase()</code></li>
</ul>
<blockquote>
<p> <code>target</code> is a property in the event object <code>e</code>, which tells what element the event is applied to.</p>
<p><code>value</code> is also a property but on the target property, which tells the value typed in the input.</p>
<p><code>toLowerCase()</code> is a method on the <code>value</code> property. This makes the inputted values if uppercase become lowercase.</p>
</blockquote>
<p>Here's where the main functionality is applied. </p>
<pre><code class="lang-js">  <span class="hljs-comment">// Filters the todo</span>
  [...todos].forEach(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
    <span class="hljs-keyword">let</span> todoContent = todo.textContent;
    <span class="hljs-keyword">if</span> (todoContent.toLowerCase().includes(searching)) {
      todo.style.display = <span class="hljs-string">'block'</span>;
    } <span class="hljs-keyword">else</span> {
      todo.style.display = <span class="hljs-string">'none'</span>;
    }
  });
</code></pre>
<ul>
<li><p>Using <code>[...todos]</code> converts the Nodelist Object to an array, given us access to the <code>forEach()</code> method.
<br /></p>
<blockquote>
<p>Well, the <code>forEach()</code> method is available to the Nodelist object, but not all the array methods all available on the Nodelist Object. Then why convert it to an array you might ask, well for consistency sake.</p>
</blockquote>
</li>
<li><p>In the <code>forEach()</code> function, which loops over each todo item a variable <code>todoContent</code> is declared with it's value as the <code>todo.textContent</code>.
<br /></p>
<blockquote>
<p><code>todo</code> are each item in the array which are the list -<code>&lt;li&gt;</code> elements.
<code>textContent</code> is a property that's available to each list elements which returns the value of the lists.</p>
</blockquote>
</li>
<li><p>Next line is an if statement condition which checks if <code>todoContent.toLowerCase()</code> includes/has <code>seaching</code> which is what is being inputted.
<br /></p>
<blockquote>
<p>Simply the above statement can be represented like this <code>"Hello there!".includes("!")</code>
From the representation, it evaluates to <code>true</code>.</p>
</blockquote>
</li>
<li><p>If the condition in the if statement is <code>true</code> at any point in time, then the list elements will be visible <code>display: block</code> - <code>todo.style.display = 'block'</code> other wise the list elements will be invisible <code>display: none</code> - <code>todo.style.display = 'none'</code>.</p>
</li>
</ul>
<p>That's the functionality, I know right pretty easy, but I had a hard time making it work and also had to watch a <a target="_blank" href="https://youtu.be/3NG8zy0ywIk">video</a> that gave me insight into how to implement it.</p>
<p>Now, what if we'll like to tell a user if what's searched in the input element isn't found. Hmm, this is going to be tricky but let's play things out.</p>
<p>Within the same function <code>filterFunction()</code> type in the snippet of code below.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Displays No Todo Found</span>
  <span class="hljs-keyword">let</span> result = [...todos].every(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> todo.style.display === <span class="hljs-string">'none'</span>;
  });

  result === <span class="hljs-literal">true</span>
    ? (notFound.style.display = <span class="hljs-string">'block'</span>)
    : (notFound.style.display = <span class="hljs-string">'none'</span>);
</code></pre>
<ul>
<li><p>First line, a variable is declared <code>result</code> with its value which is to be a Boolean value (<code>true</code> or <code>false</code>).
<br /></p>
<blockquote>
<p><code>
[...todos].every(todo =&gt; {
  return todo.style.display === 'none';
});
</code>
<br />
<br />
The Nodelist object is converted to an array, giving it access to the <code>every</code> method which checks if every item (list element) in the array has a <code>style.display === 'none'</code>. If this condition is true the <code>every</code> method return <code>true</code> and if not returns <code>false</code>.</p>
</blockquote>
</li>
<li><p>Next off, there's a ternary operation which checks if <code>result</code> is <code>true</code>. If <code>true</code> the element <code>notFound</code> (<code>&lt;div id="notFound"&gt; &lt;p&gt;...&lt;/p&gt;&lt;/div&gt;</code>) will be displayed - <code>notFound.style.display = 'block'</code> else it wouldn't be displayed - <code>notFound.style.display = 'none'</code>.
<br /></p>
<blockquote>
<p>The above explanation displays the text "No Todo Found" when the search input isn't found.</p>
</blockquote>
</li>
</ul>
<p><a target="_blank" href="https://jomefavourite.github.io/Filter_Functionality_Javascript/">Demo</a></p>
<p><a target="_blank" href="https://github.com/jomefavourite/Filter_Functionality_Javascript">Code here</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Well, I that's all if you have any question you could comment below or leave message me on <a target="_blank" href="https://twitter.com/FavouriteJome1">Twitter</a>.</p>
<p>Hope the article was useful or will be useful later on. Thanks for reading.</p>
]]></content:encoded></item><item><title><![CDATA[Let's build a game using JavaScript]]></title><description><![CDATA[Hello 👋, In this article, I'll share how I built my first game written in Javascript and my thought process in making the game. Hope you'll follow along and learn something new. Okay then, let's go over the rules of the game for us to understand the...]]></description><link>https://blog.favouritejome.dev/lets-build-a-game-using-javascript</link><guid isPermaLink="true">https://blog.favouritejome.dev/lets-build-a-game-using-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Sass]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[game]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Fri, 23 Apr 2021 17:37:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1619198242570/il5yuSWgy.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello 👋, In this article, I'll share how I built my first game written in Javascript and my thought process in making the game. Hope you'll follow along and learn something new. Okay then, let's go over the rules of the game for us to understand the game.</p>
<p>If you've ever played the game called Rock, Paper, Scissors you'll already be familiar with the rules of the game. But if you've never played the game, here are the rules:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1618586104378/o8zqaHOb0.jpeg" alt="mobile-rules-modal.jpg" /></p>
<h2 id="heading-prerequisite">Prerequisite</h2>
<ul>
<li>Basic knowledge of HTML</li>
<li>Basic knowledge of CSS</li>
<li>Basic knowledge of the Command Line Interface</li>
<li>Basic knowledge of JavaScript</li>
</ul>
<h2 id="heading-why-i-took-this-challenge">Why I took this challenge?</h2>
<blockquote>
<p>Storytime 😁, if you're not interested <a class="post-section-overview" href="#next1">click here</a> to move to the next section.</p>
</blockquote>
<p>Before why, this challenge was provided by <a target="_blank" href="https://www.frontendmentor.io">frontendmentor.io</a>, which is an amazing platform to test and improve your Frontend skills. I'll advise you to check out some of the challenges on the platform yourself.</p>
<p>Click here to download this project file from <a target="_blank" href="https://www.frontendmentor.io/challenges/rock-paper-scissors-game-pTgwgvgH">frontendmentor.io</a> so that you can follow along. <em>It's totally fine if you don't want to get the project file, just reading how I made it is fine.</em></p>
<p>Before agreeing to attempt this challenge I've always run away from the challenge saying it looks too complex not until I saw that <a class="user-mention" href="https://hashnode.com/@VickyIkechukwu">Victor Ikechukwu</a> had completed the challenge. I was amazed that he had already done the challenge I considered hard, so I made up my mind to take up the challenge, how hard could it be? I said.</p>
<p>Here's the live demo if you'll like to play the game:</p>
<ul>
<li><a target="_blank" href="https://rock-paper-scissors-game-zeta-one.vercel.app/">Live Demo</a></li>
<li><a target="_blank" href="https://github.com/jomefavourite/Frontendmentor_rock-paper-scissors-master">Github code</a></li>
</ul>
<h2 id="heading-set-goals-i-implemented-lessspan-idnext1greaterlessspangreater">Set goals I implemented <span id="next1"></span></h2>
<blockquote>
<p>Another storytime 😁, if you would like to skip the section <a class="post-section-overview" href="#next2">click here.</a></p>
</blockquote>
<p>Upon every challenge I take, I'll always want to try something new, so I planned out what I'll like to practice and learn while on the challenge.</p>
<ul>
<li>Making use of Dart SCSS/SASS (Syntactically Awesome Style Sheets) which I had never used.</li>
<li>Making use of just vanilla JavaScript.</li>
<li>Making use of Functional Programming Paradigm to the best of my abilities and lastly</li>
<li>Using BEM (Block Element Modifier) methodology for naming class names.</li>
</ul>
<p>Actually, I got the idea of implementing the functional programming paradigm, after reading this article <a target="_blank" href="https://saurabhkamboj.hashnode.dev/functional-programming-with-javascript">Functional Programming with JavaScript</a> by <a class="user-mention" href="https://hashnode.com/@saurabhkamboj">Saurabh Kamboj</a>. </p>
<p>I've never been a big fan of the Object-Oriented Paradigm, so why not learn the Functional Programming Paradigm instead, I concluded.</p>
<h2 id="heading-setup-for-the-project-lessspan-idnext2greaterlessspangreater">Setup for the project <span id="next2"></span></h2>
<p>Whenever a challenge is downloaded from <a target="_blank" href="https://www.frontendmentor.io/challenges">frontendmentor.io</a> all files needed like the HTML file with all the text used for the challenge, the colours used and also the designs for both mobile and the desktop view will be provided.</p>
<blockquote>
<p>For the next couple of steps, we'll need Node.js installed first, which comes with NPM (Node Package Manager) for us to get started.</p>
<p>Click here to download <a target="_blank" href="https://nodejs.org/en/">Node.js</a></p>
</blockquote>
<p>First thing first, we'll need to run this command <code>npm init -y</code> on the terminal to keep track of all the dependencies for the project.</p>
<blockquote>
<p>Dependencies are the packages that are being used in the code of the project. For example, if my application is working with SASS then there may be a dependency of SASS node package in the application.</p>
<p><a target="_blank" href="https://javascript.plainenglish.io/what-the-dependency-types-of-dependencies-in-a-node-js-application-explained-904a5424fbd3">Click here to read more about what's dependencies.</a></p>
</blockquote>
<p>Running the above command will generate a <code>package.json</code> file which shows the dependencies used in the project and also information about the project, for now, there are no dependencies.</p>
<p>Then to install SASS, from NPM (Node Package Manager) through Node, type in the command below on the terminal which installs <code>sass</code> globally on your system.</p>
<pre><code><span class="hljs-built_in">npm</span> install -g sass
</code></pre><blockquote>
<p>-g is a flag that represents global</p>
<p>I've written an introductory article about SASS, you could read that by <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">clicking here</a>.</p>
</blockquote>
<p>Now that <code>sass</code> has been installed globally on our system, we'll need to install it on our project directory, to make it work in the directory through this command.</p>
<pre><code><span class="hljs-built_in">npm</span> install sass
</code></pre><blockquote>
<p>Notice, two files will be added to the project directory</p>
<p><code>./node_modules</code> which contains libraries downloaded from npm for <code>sass</code> to work.</p>
<p><code>package_lock.json</code> which contains the several dependencies <code>sass</code> needs to work.</p>
</blockquote>
<p>Yes! finally, we've got SASS installed and ready to be used. Now, the next step is to open the <code>package.json</code> file. We'll need to add a command that compiles our SASS files into a plain CSS file which the browser understands.</p>
<p>Navigate to the <code>"script"</code> key, replacing it with the command below</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"start"</span> : <span class="hljs-string">"sass --watch scss:css"</span>
},
</code></pre>
<p>Once the command is set up, we can watch the changes made in the <code>scss</code> folder which will be containing all our SCSS modules and then generates a <code>css</code> folder with the plain CSS, to which the HTML file will be linked to.</p>
<p>From the command above, <code>sass</code> watches every file in the directory/folder named <strong>scss</strong> and compiles all the SCSS files into a single CSS file in the directory/folder named <strong>css</strong>. The CSS file compiled is what the browser can read and interpret.</p>
<p>To initialise the watch, type the command below into the terminal.</p>
<pre><code>npm <span class="hljs-keyword">start</span>
</code></pre><p>By doing this every change in the scss folder containing the <code>scss</code> files will be compiled into one <code>css</code> file.</p>
<blockquote>
<p>Don't run the command yet, because we don't have our scss folder created yet</p>
</blockquote>
<p>The next step is to create a folder named <strong>scss</strong>, which will contain all the scss files needed for the project. When the folder is created, create a new file named <code>_base.scss</code>.</p>
<p><code>_base.scss</code> is a partial file that's not compiled until it's imported to the main stylesheet style.scss. This file contains resets, variables, mixins, and any utility classes used throughout the project.</p>
<p>Since we are making use of colours that have been provided in the <code>style-guide.md</code> file by Frontend mentor, open the <code>style-guide.md</code> file copy all the colours including their names, into the <code>_bass.scss</code> file.</p>
<p>After copying the colours, make it have the structure as shown below.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* _base.scss */</span>

<span class="hljs-selector-pseudo">:root</span> {
  <span class="hljs-attribute">--scissorsGradient</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">39</span>, <span class="hljs-number">89%</span>, <span class="hljs-number">49%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">40</span>, <span class="hljs-number">84%</span>, <span class="hljs-number">53%</span>));
  <span class="hljs-attribute">--paperGradient</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">230</span>, <span class="hljs-number">89%</span>, <span class="hljs-number">62%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">230</span>, <span class="hljs-number">89%</span>, <span class="hljs-number">65%</span>));
  <span class="hljs-attribute">--rockGradient</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">349</span>, <span class="hljs-number">71%</span>, <span class="hljs-number">52%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">349</span>, <span class="hljs-number">70%</span>, <span class="hljs-number">56%</span>));
  <span class="hljs-attribute">--lizardGradient</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">261</span>, <span class="hljs-number">73%</span>, <span class="hljs-number">60%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">261</span>, <span class="hljs-number">72%</span>, <span class="hljs-number">63%</span>));
  <span class="hljs-attribute">--cyan</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">189</span>, <span class="hljs-number">59%</span>, <span class="hljs-number">53%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">189</span>, <span class="hljs-number">58%</span>, <span class="hljs-number">57%</span>));

  <span class="hljs-attribute">--darkText</span>: <span class="hljs-built_in">hsl</span>(<span class="hljs-number">229</span>, <span class="hljs-number">25%</span>, <span class="hljs-number">31%</span>);
  <span class="hljs-attribute">--scoreText</span>: <span class="hljs-built_in">hsl</span>(<span class="hljs-number">229</span>, <span class="hljs-number">64%</span>, <span class="hljs-number">46%</span>);
  <span class="hljs-attribute">--headerOutline</span>: <span class="hljs-built_in">hsl</span>(<span class="hljs-number">217</span>, <span class="hljs-number">16%</span>, <span class="hljs-number">45%</span>);

  <span class="hljs-comment">/* Background */</span>
  <span class="hljs-attribute">--radialGradient</span>: <span class="hljs-built_in">linear-gradient</span>(hsl(<span class="hljs-number">214</span>, <span class="hljs-number">47%</span>, <span class="hljs-number">23%</span>), <span class="hljs-built_in">hsl</span>(<span class="hljs-number">237</span>, <span class="hljs-number">49%</span>, <span class="hljs-number">15%</span>));
}
</code></pre>
<blockquote>
<p>I decided to make use of the css custom variable for the project instead of scss variable, why? I don't know 😂.</p>
</blockquote>
<p>The next step is to click on the link to the font at the <code>style-guide.md</code> file to grab it from google fonts. Adding the <code>@import</code> rule with the font name to the <code>body</code> selector.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* _base.scss */</span>

<span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:wght@400;600;700&amp;display=swap'</span>);

<span class="hljs-selector-pseudo">:root</span> {...}

<span class="hljs-selector-tag">body</span> {
   <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Barlow Semi Condensed'</span>, sans-serif;
}
</code></pre>
<p>Now that we got all our set up ready, it's time to actually start coding, by inputting the command we failed to run since we didn't have <strong>scss folder</strong> before.</p>
<pre><code>npm <span class="hljs-keyword">start</span>
</code></pre><p>By running the command above, a css folder is auto-created containing the <code>style.css</code> and <code>style.css.map</code> files.</p>
<h2 id="heading-lets-start-coding">Let's start coding</h2>
<p>Before proceeding any further, let's take a look at the project folder structure, to make sure we are at the same pace.</p>
<pre><code>css
|__ style.css
|__ style.css.<span class="hljs-keyword">map</span>
design
|__ ....
images
|__ ....
node_modules
|__ ....
scss
|__ ....
.gitignore
index.html
main.js
<span class="hljs-keyword">package</span>-lock.json
<span class="hljs-keyword">package</span>.json
README-template.md
README.md
style-guide.md
</code></pre><p>Okay then, the HTML file is shown below, notice the class names are all named following the BEM (Block Element Modifier) methodology (at least most of them 😃).</p>
<blockquote>
<p>Read this article to know more about <a target="_blank" href="https://css-tricks.com/bem-101/">BEM</a> <span id="bem"></span></p>
</blockquote>
<p>If you're wondering why BEM, it just makes it easier when nesting in SASS, plus a whole lot of advantages. Please find them out using the <a class="post-section-overview" href="#bem">link above</a>.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    ...
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"css/style.css"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"heading"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/logo.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"logo"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"score__display"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Score<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"score"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span>&gt;</span>0<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"game"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"game__paper__scissors"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button game__button--paper"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"paper button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"paper"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-paper.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-paper"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button game__button--scissors"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Scissors button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"scissors"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-scissors.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-scissors"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
          <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button game__button--rock rock-button"</span>
          <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
          <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"rock button"</span>
          <span class="hljs-attr">id</span>=<span class="hljs-string">"rock"</span>
        &gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-rock.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-rock"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"play__again"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"winLoseDraw"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"playAgain"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-sec"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"play again"</span>&gt;</span>
          Play Again
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-pry"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"rules"</span>&gt;</span>Rules<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

   <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"attribution"</span>&gt;</span>
      Challenge by
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.frontendmentor.io?ref=challenge"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>
        &gt;</span>Frontend Mentor<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>
      &gt;</span>. Coded by
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://jomefavourite.github.io/linktree/"</span>&gt;</span>Favourite Jome<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- Modal for the game rules --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal__container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Rules<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
              <span class="hljs-attr">class</span>=<span class="hljs-string">"closeBtn desktopCloseBtn"</span>
              <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-close.svg"</span>
              <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-close"</span>
            /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-rules"</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/image-rules.svg"</span>
            <span class="hljs-attr">alt</span>=<span class="hljs-string">"image-rules"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"closeBtn mobileCloseBtn"</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-close.svg"</span>
            <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-close"</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- Template for the game --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"gameTemplate"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"game__grade"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button user__button"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"paper button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"paper"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-paper.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-paper"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button computer__button"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Scissors button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"scissors"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>From the HTML file above, there's a strange element named <code>template</code>. </p>
<pre><code class="lang-HTML">   <span class="hljs-comment">&lt;!-- Template for the game --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"gameTemplate"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"game__grade"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button user__button"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"paper button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"paper"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./images/icon-paper.svg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"icon-paper"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"game__button computer__button"</span>
            <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Scissors button"</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"scissors"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
</code></pre>
<p>If you've seen this element before, very good, if not all it does is hide the child elements from the browser and can only be shown using Javascript by adding it to the DOM (Document Object Model).</p>
<p>I got the idea of using the <code>template</code> element from an article I read, sadly I can't find it.</p>
<blockquote>
<p>From MDN, the <code>template</code> element is a mechanism for holding HTML that is not to be rendered immediately when a page is loaded but may be instantiated subsequently during runtime using JavaScript.</p>
<p>Read more about the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template">template element here</a></p>
</blockquote>
<p>Also, if you've ever seen a Vue.js source code, you'll notice the <code>template</code> element is used.</p>
<p><strong> Why I used the template element </strong></p>
<p>I used the <code>template</code> element to hide its child elements from the DOM (Document Object Model) until a certain action/event is done using JavaScript which then appends the child elements of the <code>template</code> element into the <abbr>DOM</abbr>. The implementation is done in the Javascript section.</p>
<h3 id="heading-sass">SASS</h3>
<p>As for the styling of our project, we'll be making use of the <code>scss</code> extension which is more like writing CSS but still with all the <code>SASS</code> features.</p>
<blockquote>
<p>If the statement above seems confusing, then please read this article - <a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">Write CSS with Superpowers Using Sass.</a> where I've covered the differences between <code>SCSS</code> and <code>SASS</code>.</p>
</blockquote>
<p>Here the folder structure of all the <code>scss</code> file used in the project.</p>
<pre><code>scss
<span class="hljs-params">|  _base.scss
|</span>  _components.scss
<span class="hljs-params">|  _desktop.scss
|</span>  _medium.scss
<span class="hljs-params">|  _mixins.scss
|</span>  style.scss
</code></pre><p>The <code>_</code> before the <code>scss</code> file, symbolises it's a partial file, which means it should not be compiled until when used in the main <code>style.scss</code> file.</p>
<ul>
<li><code>_base.scss</code>  contains styles such as resets and typographic rules, which are commonly used throughout your project.</li>
<li><code>_components.scss</code> contains all the CSS that handles the layout.</li>
<li><code>_desktop.scss</code> contains all the CSS rules for the desktop view.</li>
<li><code>_medium.scss</code> contains all the CSS rules for the tablet view.</li>
<li><code>_mixins.scss</code> contains all the mixins created for the project.</li>
</ul>
<blockquote>
<p><a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass#mixins">Click here to know more about mixins</a></p>
</blockquote>
<ul>
<li><code>style.scss</code> contains all the imports for the above files.</li>
</ul>
<p>The two main features of Dart SASS I got to try out was <code>@use</code> rule and <code>@forward</code> rule.</p>
<ul>
<li>The <code>@use</code> rule loads mixins, functions, and variables from other Sass stylesheets, and combines CSS from multiple stylesheets together while</li>
<li>The <code>@forward</code>rule loads a Sass stylesheet and makes its mixins, functions, and variables available when your stylesheet is loaded with the @use rule.</li>
</ul>
<p>The two rules mentioned above are part of the newer features of Sass, which is to replace the use of the <code>@import</code> rule.</p>
<h3 id="heading-javascript">JavaScript</h3>
<p>Javascript, the brain of the project! Before diving into the functionality of the game, here's a breaking down of how the game should be implemented.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619024218407/jKXzr1Cur.jpeg" alt="Sketch003.jpg" /></p>
<p>From the image above, you'll notice there are steps needed to be taken, before declaring the winner. The user will have to click on either the Rock, Paper or Scissors button. Then after a few seconds, the computer makes its choice and then finally a winner is declared.</p>
<p>As for the score for the game, I decided to implement it this way, if a user wins the score should be incremented by 1 (+1) while if the computer wins the score should be decremented by 1 (-1).</p>
<p>Now let's dive into the program.</p>
<pre><code class="lang-js"><span class="hljs-comment">// selecting the DOM</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">select</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">document</span>.querySelector(name);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">selectAll</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">document</span>.querySelectorAll(name);
}

<span class="hljs-keyword">const</span> rulesBtn = select(<span class="hljs-string">'#rules'</span>);
<span class="hljs-keyword">const</span> closeBtns = selectAll(<span class="hljs-string">'.closeBtn'</span>);
<span class="hljs-keyword">const</span> rock = select(<span class="hljs-string">'#rock'</span>);
<span class="hljs-keyword">const</span> paper = select(<span class="hljs-string">'#paper'</span>);
<span class="hljs-keyword">const</span> scissors = select(<span class="hljs-string">'#scissors'</span>);
<span class="hljs-keyword">const</span> scoreResult = select(<span class="hljs-string">'#score'</span>);
<span class="hljs-keyword">const</span> modal = select(<span class="hljs-string">'#modal'</span>);
</code></pre>
<p>From the above code, two functions were declared <code>select()</code> and <code>selectAll()</code>, which returns <code>document.querySelector(name)</code> and <code>document.querySelectorAll(name)</code> respectively. Using this functions,  enables me to select my DOM elements quickly and by typing less. </p>
<p>Also this way I'm following the Functional Programming paradigm rules, which are</p>
<ul>
<li><p>Using Pure Functions: Pure Functions are the functions that depend only on their input and nothing else i.e they'll have some input values and based on those input values they'll always return an output. <cite>From <a target="_blank" href="https://saurabhkamboj.hashnode.dev/functional-programming-with-javascript">Functional Programming with JavaScript</a> by  <a class="user-mention" href="https://hashnode.com/@saurabhkamboj">Saurabh Kamboj</a></cite></p>
</li>
<li><p>Avoid Side Effects: Side effects are a modification to the outside world, avoid interacting with the global scope.</p>
</li>
</ul>
<blockquote>
<p>There are many more rules, to learn more read these articles <a target="_blank" href="https://saurabhkamboj.hashnode.dev/functional-programming-with-javascript">Functional Programming with JavaScript</a> and <a target="_blank" href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0">Master the JavaScript Interview: What is Functional Programming?</a></p>
</blockquote>
<p>Next off, a variable <code>score</code> is declared having a function <code>lS()</code> which is invoked. The function <code>ls()</code> checks if the key <code>score</code> is added to the localStorage. If the key exists then the value is returned as a Number else <code>0</code> is returned.</p>
<p>On the next line, the <code>scoreResult.innerHTMl</code>  has its value also to the function <code>ls()</code> which return the score from the localStorage.</p>
<p>Then several event listeners are declared.</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> score = lS(<span class="hljs-number">0</span>);
scoreResult.innerHTML = lS(<span class="hljs-number">0</span>);

<span class="hljs-comment">// LocalStorage functionality</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">lS</span>(<span class="hljs-params">initialValue</span>) </span>{
  <span class="hljs-keyword">const</span> localData = <span class="hljs-built_in">localStorage</span>.key(<span class="hljs-string">'score'</span>);
  <span class="hljs-keyword">return</span> localData ? <span class="hljs-built_in">Number</span>(<span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'score'</span>)) : initialValue;
}

<span class="hljs-comment">// Event Listeners</span>
rock.addEventListener(<span class="hljs-string">'click'</span>, playGame);
paper.addEventListener(<span class="hljs-string">'click'</span>, playGame);
scissors.addEventListener(<span class="hljs-string">'click'</span>, playGame);
rulesBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> openCloseModal(modal));
closeBtns.forEach(<span class="hljs-function"><span class="hljs-params">closeBtn</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> closeBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> openCloseModal(modal));
});
</code></pre>
<p>Notice that <code>rock</code>, <code>paper</code> and <code>scissors</code> variables which are the buttons (<em>actually I used the div element with the role of a button in the HTML file but I'm just going to call it buttons because it's clicked on</em>) clicked on by the user to initiate the game has a function to its event listener named `play games. </p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">playGame</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> userChoice = <span class="hljs-built_in">this</span>.id;
  <span class="hljs-keyword">const</span> computerChoice = computerRandom([<span class="hljs-string">'rock'</span>, <span class="hljs-string">'paper'</span>, <span class="hljs-string">'scissors'</span>]);
  <span class="hljs-keyword">const</span> game = select(<span class="hljs-string">'.game'</span>);

  <span class="hljs-keyword">const</span> {userButton, computerButton} = gameTemplate(userChoice, computerChoice);
  <span class="hljs-keyword">const</span> result = rules(userChoice, computerChoice);

  game.classList.add(<span class="hljs-string">'max__width'</span>);

  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (result === <span class="hljs-string">'win'</span>) {
      scoreResult.innerHTML = add();
      userButton.classList.add(<span class="hljs-string">'winner__boxShadow'</span>);
    }
    <span class="hljs-keyword">if</span> (result === <span class="hljs-string">'lose'</span>) {
      scoreResult.innerHTML = subtract();
      computerButton.classList.add(<span class="hljs-string">'winner__boxShadow'</span>);
    }
  }, <span class="hljs-number">400</span>);

  <span class="hljs-keyword">return</span> winLose(result);
}
</code></pre>
<p>Now let's go over the function to figure out how it works.</p>
<ul>
<li><p>Line 1 in the function <code>playGame()</code> : <code>const userChoice = this.id;</code> <br />
This is to get the users choice, since multiple buttons have the same function, we'll need to know what button was clicked.<br />
<br />
That's why the <code>this</code> keyword is used to get the attribute on the element <code>id</code>.<br />
So if the rock button is clicked <code>&lt;div class="game__button ..." role="button" aria-label="rock button" id="rock"&gt;...&lt;/div&gt;</code> the <code>id</code> attribute will be returned.</p>
</li>
<li><p>Line 2 in the function: <code>const computerChoice = computerRandom(['rock', 'paper', 'scissors']);</code> <br />
Here a function <code>computerRandom()</code> is invoked with its argument as an array that randomly gets an item from the parameter array. 
<br /></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">computerRandom</span>(<span class="hljs-params">games</span>) </span>{
  <span class="hljs-keyword">return</span> games[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * games.length)];
}
</code></pre>
</li>
<li><p>At line 5:
<code>const {userButton, computerButton} = gameTemplate(userChoice, computerChoice);</code><br />
<br />
The function <code>gameTemplate()</code> which will be returning an object is where all the magic happens. Here's the function that takes the contents of the <code>template</code> element and adds it to the DOM<br /></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gameTemplate</span>(<span class="hljs-params">userChoice, computerChoice</span>) </span>{
<span class="hljs-keyword">if</span> (<span class="hljs-string">'content'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'template'</span>)) {
  <span class="hljs-keyword">const</span> game = select(<span class="hljs-string">'.game'</span>);
  <span class="hljs-keyword">const</span> template = select(<span class="hljs-string">'#gameTemplate'</span>);

  game.style.backgroundImage = <span class="hljs-string">'none'</span>;
  game.children[<span class="hljs-number">0</span>].style.display = <span class="hljs-string">'none'</span>;
  game.children[<span class="hljs-number">1</span>].style.display = <span class="hljs-string">'none'</span>;

  <span class="hljs-keyword">const</span> clone = template.content.cloneNode(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> gameButton = clone.querySelectorAll(<span class="hljs-string">'.game__button'</span>);
  gameButton[<span class="hljs-number">0</span>].classList.add(<span class="hljs-string">`game__button--<span class="hljs-subst">${userChoice}</span>`</span>);
  gameButton[<span class="hljs-number">0</span>].children[<span class="hljs-number">0</span>].children[<span class="hljs-number">0</span>].src = <span class="hljs-string">`./images/icon-<span class="hljs-subst">${userChoice}</span>.svg`</span>;

  gameButton[<span class="hljs-number">1</span>].style.backgroundColor = <span class="hljs-string">'rgba(0, 0, 0, 0.15)'</span>;
  gameButton[<span class="hljs-number">1</span>].children[<span class="hljs-number">0</span>].style.display = <span class="hljs-string">'none'</span>;

  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    gameButton[<span class="hljs-number">1</span>].children[<span class="hljs-number">0</span>].style.display = <span class="hljs-string">'flex'</span>;
    <span class="hljs-keyword">const</span> img = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'img'</span>);
    img.setAttribute(<span class="hljs-string">'src'</span>, <span class="hljs-string">`./images/icon-<span class="hljs-subst">${computerChoice}</span>.svg`</span>);
    img.setAttribute(<span class="hljs-string">'alt'</span>, <span class="hljs-string">`icon-<span class="hljs-subst">${computerChoice}</span>`</span>);
    gameButton[<span class="hljs-number">1</span>].classList.add(<span class="hljs-string">`game__button--<span class="hljs-subst">${computerChoice}</span>`</span>);
    gameButton[<span class="hljs-number">1</span>].children[<span class="hljs-number">0</span>].appendChild(img);
  }, <span class="hljs-number">400</span>);

  game.appendChild(clone.firstElementChild);

  <span class="hljs-keyword">return</span> {<span class="hljs-attr">userButton</span>: gameButton[<span class="hljs-number">0</span>], <span class="hljs-attr">computerButton</span>: gameButton[<span class="hljs-number">1</span>]};
}
}
</code></pre>
<p><br />
<em>I'm sorry I wouldn't go over everything in this function line by line, but I'll go over the main functionalities.</em><br />
<br />
Okay then let's exact the main statements from the above function<br />
<br /></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">gameTemplate</span>(<span class="hljs-params">userChoice, computerChoice</span>) </span>{
 <span class="hljs-keyword">if</span> (<span class="hljs-string">'content'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'template'</span>)) {
    <span class="hljs-keyword">const</span> game = select(<span class="hljs-string">'.game'</span>);
    <span class="hljs-keyword">const</span> template = select(<span class="hljs-string">'#gameTemplate'</span>);
    <span class="hljs-keyword">const</span> clone = template.content.cloneNode(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">const</span> gameButton = clone.querySelectorAll(<span class="hljs-string">'.game__button'</span>);

    gameButton[<span class="hljs-number">0</span>] <span class="hljs-comment">// userChoice Button</span>
    gameButton[<span class="hljs-number">1</span>] <span class="hljs-comment">// computerChoice Button</span>

    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
         gameButton[<span class="hljs-number">1</span>]
         ....
    }, <span class="hljs-number">400</span>)

   game.appendChild(clone.firstElementChild);

   <span class="hljs-keyword">return</span> {<span class="hljs-attr">userButton</span>: gameButton[<span class="hljs-number">0</span>], <span class="hljs-attr">computerButton</span>: gameButton[<span class="hljs-number">1</span>]};
 }
 <span class="hljs-keyword">return</span>;
}
</code></pre>
<p><br />
From the function above there's a check if <code>'content'</code> exist <code>document.createElement('template'))</code> which checks if the browser supports the template element.<br /><br />
Next off, the element with the class of <code>.game</code> is selected, then id of <code>#gameTemplate</code>. On the next line <code>const clone = template.content.cloneNode(true);</code>, this is to ensure we can clone the contents in the <code>template</code> element. <br /><br />
Then the <code>gameButton</code> is selected from the clone. Where <code>gameButton[0]</code> is the users button
and <code>gameButton[1]</code> is the computer button. Also notice, there's a delay of 400ms on <code>gameButton[1]</code> so that it appears as if that it takes some time to compute. <br /><br />
Next off, the <code>clone</code> element gets appended to the <code>game</code> element via the DOM and both <code>gameButton[0]</code> and <code>gameButton[1]</code> are returned in an object.<br /><code>{userButton: gameButton[0], computerButton: gameButton[1]}</code></p>
</li>
<li><p>At line 6 in the <code>playGame()</code> function: <code>const result = rules(userChoice, computerChoice);</code><br /><br />
We'd notice another function <code>rules()</code> which is being invoked with the arguments<code>userChoice, computerChoice</code>.<br />
<br /></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span>(<span class="hljs-params">userChoice, computerChoice</span>) </span>{
<span class="hljs-keyword">if</span> (userChoice === computerChoice) {
  <span class="hljs-keyword">return</span> <span class="hljs-string">`draw`</span>;
}

<span class="hljs-keyword">switch</span> (userChoice) {
  <span class="hljs-keyword">case</span> <span class="hljs-string">'paper'</span>: {
    <span class="hljs-keyword">return</span> computerChoice === <span class="hljs-string">'rock'</span> ? <span class="hljs-string">'win'</span> : <span class="hljs-string">'lose'</span>;
    <span class="hljs-keyword">break</span>;
  }
  <span class="hljs-keyword">case</span> <span class="hljs-string">'rock'</span>: {
    <span class="hljs-keyword">return</span> computerChoice === <span class="hljs-string">'scissors'</span> ? <span class="hljs-string">'win'</span> : <span class="hljs-string">'lose'</span>;
    <span class="hljs-keyword">break</span>;
  }
  <span class="hljs-keyword">case</span> <span class="hljs-string">'scissors'</span>: {
    <span class="hljs-keyword">return</span> computerChoice === <span class="hljs-string">'paper'</span> ? <span class="hljs-string">'win'</span> : <span class="hljs-string">'lose'</span>;
    <span class="hljs-keyword">break</span>;
  }
}

<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
</code></pre>
<p><br />
All the function does is to determine who wins, loses and if it's a draw.</p>
</li>
</ul>
<ul>
<li><p>At line 20, the returned function is invoked <code>winLose(result)</code> with the result as its argument. <br />
<br />
This function is to determine the message that will be prompted out if the user wins, loses or if its a draw.<br />
<br />
Also the function returns a variable <code>playAgain</code> with the event listener which when clicked on the game is played again.
<br /></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">winLose</span>(<span class="hljs-params">result</span>) </span>{
<span class="hljs-keyword">const</span> playAgainBtn = select(<span class="hljs-string">'#playAgain'</span>);
<span class="hljs-keyword">const</span> playAgain = select(<span class="hljs-string">'.play__again'</span>);
<span class="hljs-keyword">const</span> game = select(<span class="hljs-string">'.game'</span>);
<span class="hljs-keyword">const</span> winLoseDraw = select(<span class="hljs-string">'#winLoseDraw'</span>);

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
 playAgain.style.display = <span class="hljs-string">'block'</span>;
 <span class="hljs-keyword">if</span> (result === <span class="hljs-string">'win'</span>) {
   winLoseDraw.innerHTML = <span class="hljs-string">'You Win'</span>;
 }
 <span class="hljs-keyword">if</span> (result === <span class="hljs-string">'lose'</span>) {
   winLoseDraw.innerHTML = <span class="hljs-string">'You Lose'</span>;
 }
 <span class="hljs-keyword">if</span> (result === <span class="hljs-string">'draw'</span>) {
   winLoseDraw.innerHTML = <span class="hljs-string">"It's a Draw"</span>;
 }
}, <span class="hljs-number">400</span>);

<span class="hljs-keyword">return</span> playAgainBtn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
 playAgainFn(game, playAgain);
});
</code></pre>
</li>
</ul>
<p>OMG, that's a lot of information to process, I know. From the above steps, we've covered all the main functions that make the game work.</p>
<p>Once again here's the: </p>
<ul>
<li><a target="_blank" href="https://rock-paper-scissors-game-zeta-one.vercel.app/">Live Demo</a></li>
<li><a target="_blank" href="https://github.com/jomefavourite/Frontendmentor_rock-paper-scissors-master">Github code</a></li>
</ul>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><a target="_blank" href="https://javascript.plainenglish.io/what-the-dependency-types-of-dependencies-in-a-node-js-application-explained-904a5424fbd3#:~:text=These%20are%20the%20packages%20that,may%20use%20npm%20i%20package_name">Different types of dependencies in a Node.js application explained</a></li>
<li><a target="_blank" href="https://itnext.io/structuring-your-sass-projects-c8d41fa55ed4">Structuring your Sass Projects</a></li>
<li><a target="_blank" href="https://favouritejome.hashnode.dev/write-css-with-superpowers-using-sass">Write CSS with Superpowers Using Sass.</a></li>
<li><a target="_blank" href="https://saurabhkamboj.hashnode.dev/functional-programming-with-javascript">Functional Programming with JavaScript</a></li>
<li><a target="_blank" href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0">Master the JavaScript Interview: What is Functional Programming?</a></li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Was I able to accomplish my set goals for this project, I'd say yes. I did approach the program functionalities in a Functional Programming way, at least to my best abilities even though I know not all functions I used were pure. But hey! I did my best 😁. I also made use of BEM, SASS and plain JS.</p>
<p>If you've read so far, thank you very much, I hope you've learnt something.</p>
<p>So if you have any feedback, question, advice or any at all you could comment down below or reach me on <a target="_blank" href="https://www.twitter.com/@favouritejome1">Twitter</a></p>
<p>See you next time✌.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Pass by Value and Pass by Reference]]></title><description><![CDATA[The concept Pass by Value and Pass by Reference is one I ignored while learning vanilla JS, so when I was faced with a challenge I couldn't wrap my head around the concept. So in this article, I'll be giving instances to these concepts so as for us t...]]></description><link>https://blog.favouritejome.dev/understanding-pass-by-value-and-pass-by-reference</link><guid isPermaLink="true">https://blog.favouritejome.dev/understanding-pass-by-value-and-pass-by-reference</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[programing]]></category><dc:creator><![CDATA[Favourite Jome]]></dc:creator><pubDate>Sat, 27 Feb 2021 09:36:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1614303747230/mZbeN12Mb.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The concept Pass by Value and Pass by Reference is one I ignored while learning vanilla JS, so when I was faced with a challenge I couldn't wrap my head around the concept. So in this article, I'll be giving instances to these concepts so as for us to grasp the basics of the concept once and for all.</p>
<h2 id="heading-whats-pass-by-value">What's Pass by Value?</h2>
<p>Pass by Value is majorly used with primitive types (data types) such as:</p>
<ul>
<li><p>String</p>
</li>
<li><p>Number</p>
</li>
<li><p>Boolean</p>
</li>
<li><p>Undefined</p>
</li>
<li><p>Null</p>
</li>
</ul>
<p>Simply, <strong>Pass by Value</strong> is when a value from a variable with a primitive data type is <strong>copied</strong> with the <code>=</code> sign into another variable. Hence, the value of a primitive type is also known as a primitive value.</p>
<p>Here are instances of the five primitive types following the concept Pass by Value</p>
<pre><code class="lang-js"><span class="hljs-comment">// String</span>
<span class="hljs-keyword">let</span> name = <span class="hljs-string">"Favourite"</span>;
<span class="hljs-keyword">let</span> newName = name;

<span class="hljs-comment">// newName = "Favourite"</span>

<span class="hljs-comment">//Number</span>
<span class="hljs-keyword">let</span> count = <span class="hljs-number">50</span>;
<span class="hljs-keyword">let</span> age = count;

<span class="hljs-comment">// age = 50</span>

<span class="hljs-comment">// Boolean</span>
<span class="hljs-keyword">let</span> isNew = <span class="hljs-literal">true</span>
<span class="hljs-keyword">let</span> isFeatured = isNew

<span class="hljs-comment">// isFeatured = true</span>

<span class="hljs-comment">// Undefinded</span>
<span class="hljs-keyword">let</span> isUndefined;
<span class="hljs-keyword">let</span> empty = isUndefined

<span class="hljs-comment">// empty = undefined</span>

<span class="hljs-comment">// Null</span>
<span class="hljs-keyword">let</span> isNull = <span class="hljs-literal">null</span>
<span class="hljs-keyword">let</span> isAlsoNull = isNull

<span class="hljs-comment">// isAlsoNull = null</span>
</code></pre>
<blockquote>
<p>I know, I know, these are basic stuff in JS but did you know that the concept was called Pass by Value? Well if you did, Kudos to you if not, now you know 😀.</p>
</blockquote>
<p>With Pass by Value, the variable copied is clearly the same as the initial variable copied from, so what if the copied variable is changed?</p>
<p>Example:</p>
<pre><code class="lang-js"><span class="hljs-comment">// String</span>
<span class="hljs-keyword">let</span> name = <span class="hljs-string">"Favourite"</span>;
<span class="hljs-keyword">let</span> newName = name;

newName = <span class="hljs-string">"Success"</span>;

<span class="hljs-comment">// name = "Favourite"</span>
<span class="hljs-comment">// newName = "Success"</span>
</code></pre>
<p>Let's go through the example line by line,</p>
<ul>
<li><p>A variable is declared as <code>name</code> which has a value <code>"Favourite"</code> stored in memory and can only be addressed by the variable name <code>name</code>.</p>
</li>
<li><p>Another variable is declared as <code>newName</code> with the value <code>name</code> which is a variable and equivalent to the value <code>"Favourite"</code>. So <code>newName = "Favourite"</code> stored in memory and now addressable by the variable name <code>newName</code>.</p>
</li>
<li><blockquote>
<p>At this point, both variable <code>name</code> and <code>newName</code> has the same value but they are addressed differently with there unique variable names.</p>
</blockquote>
</li>
<li><p>Variable <code>newName</code> changes it's value to <code>"Success"</code>. Therefore, the memory space for <code>newName</code> contains the new value <code>"Success"</code>.</p>
</li>
</ul>
<blockquote>
<p>If you're unclear about what the term memory means, you can read this article <a target="_blank" href="https://favouritejome.hashnode.dev/principles-of-javascript">Principles of Javascript</a> where I discussed the term memory.</p>
</blockquote>
<p>At this point, we have different values initialised in both variables <code>name</code> and <code>newName</code>, notice that <code>name</code> still has the value <code>"Favourite"</code> even though it was copied and then changed by the variable <code>newName</code>.</p>
<blockquote>
<p>So, therefore, <strong>Pass by Value</strong> is when a variable value is copied into another variable as a value, without both variables referencing the same value even though the value might be the same. So if one of the variables change it value, there's no connection or link to the other variable.</p>
</blockquote>
<p>That's pretty much all on the concept Pass by Value.</p>
<h2 id="heading-whats-pass-by-reference">What's Pass by Reference</h2>
<p>Pass by Reference is majorly used with non-primitives types, such as</p>
<ul>
<li><p>Object</p>
</li>
<li><p>Array</p>
</li>
</ul>
<blockquote>
<p>Note: Arrays are a special type of Object</p>
</blockquote>
<h3 id="heading-object">Object</h3>
<p>When a value from a variable which is a non-primitive data type is <strong>copied</strong> with the <code>=</code> sign into another variable, the address of that value is what’s actually copied over as if it were a primitive type.<br />Objects are copied by reference instead of by value.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> obj1 = {
  <span class="hljs-attr">item1</span> : <span class="hljs-string">"Books"</span>,
  <span class="hljs-attr">item2</span>: <span class="hljs-string">"Pens"</span>
};
<span class="hljs-keyword">let</span> obj2 = obj1;

obj2.item1 = <span class="hljs-string">"Pencil"</span>

<span class="hljs-built_in">console</span>.log(obj1)
<span class="hljs-comment">// {item1: "Pencil", item2: "Pens"};</span>
<span class="hljs-built_in">console</span>.log(obj2)
<span class="hljs-comment">// {item1: "Pencil", item2: "Pens"};</span>
</code></pre>
<p>From the example above, both <code>obj1</code> and <code>obj2</code> have the same output when logged to the console, so the big question is why right?</p>
<p><strong>Why</strong></p>
<p>This is because when an object is assigned to a variable, the variable holds the address location of the object in memory and not the object itself. Thereby, the variable references the object through the address location in memory.</p>
<p>Hmm, the reason might seem daunting, so here is an illustration to help.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614302928092/SU2mVaVg6.png" alt="Learning (4).png" /></p>
<p>Let's go over the above <a class="post-section-overview" href="#objexp">example</a> line by line:</p>
<ul>
<li><p>A variable named <code>obj1</code> is declared initialized with an object as its value.</p>
<ul>
<li><p>At this point the object <code>{item1: "Books", item2: "Pens"}</code> is stored somewhere in memory having an address to where it's stored. Let's denote the address with this symbol <code>&lt;x&gt;</code>.</p>
</li>
<li><p>Then the variable <code>obj1</code> holds the address <code>&lt;x&gt;</code> to the object instead of the object value itself even though you can clearly see the object.  </p>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>All these processes happen at the JS engine.</p>
</blockquote>
<ul>
<li><p>Another variable is declared <code>obj2</code> initialized with <code>obj1</code> as a reference.</p>
<ul>
<li>Since variable <code>obj1</code> equals <code>&lt;x&gt;</code> (which is the address location to the object <code>{item1: "Books", item2: "Pens"}</code>), then variable <code>obj2</code> equals to the same address location <code>&lt;x&gt;</code> which is linked to the object <code>{item1: "Books", item2: "Pens"}</code>.</li>
</ul>
</li>
<li><p>This expression <code>obj2.item1 = "Pencil"</code> simply means change the <code>item1</code> property value to <code>"Pencil"</code> instead of <code>"Books"</code>.</p>
<ul>
<li>At this point, the variable <code>obj2</code> has changed the value to <code>{item1: "Pencil", item2: "Pens"}</code> but the address which is actually stored in the variable hasn't changed <code>&lt;x&gt;</code>. Since the address hasn't changed and the variable <code>obj1</code> also has the address <code>&lt;x&gt;</code> that means both variables <code>obj1</code> and <code>obj2</code> references the same object which is now <code>{item1: "Pencil", item2: "Pens"}</code>.</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-cloning-objects">Cloning Objects</h3>
<p>Now, that we know objects are Passed by Reference when copied as a value to another variable, so how do we stop this behaviour could be another question you might have.<br />Well, there're several ways to clone an object.</p>
<ul>
<li><strong>Object.assign() method</strong></li>
</ul>
<p><code>Object.assign()</code> is an object method that accepts arguments, where the first argument is the target object and the other arguments/argument is the source object.</p>
<p><strong>Syntax</strong>: <code>Object.assign(target, ...sources)</code></p>
<blockquote>
<p>Here's an article to read up on <code>Object.assign()</code> method in this article:<br /><a target="_blank" href="https://hashnode.com/post/es6-objectassign-method-with-example-ck5me354b04ovqps150z8mvf1">ES6 object.assign() method with Example</a> by <a class="user-mention" href="https://hashnode.com/@codesquery">Sachin Jaiswal</a></p>
</blockquote>
<p>Example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> obj = {
  <span class="hljs-attr">item1</span>: <span class="hljs-string">"Books"</span>, 
  <span class="hljs-attr">item2</span>: <span class="hljs-string">"Pens"</span>
}
<span class="hljs-keyword">let</span> cloneObj = <span class="hljs-built_in">Object</span>.assign({}, obj)

obj.item2 = <span class="hljs-string">"Pencil"</span>

<span class="hljs-built_in">console</span>.log(obj)
<span class="hljs-comment">// { item1: 'Books', item2: 'Pencil' }</span>
<span class="hljs-built_in">console</span>.log(cloneObj)
<span class="hljs-comment">// { item1: 'Books', item2: 'Pens' }</span>
</code></pre>
<ul>
<li><strong>Spread Operator</strong></li>
</ul>
<p>The spread operator also referred to as the three dots <code>...</code> is majorly used to spread out the content of an iterable i.e string, array, or objects, and thus returns a new variable.</p>
<blockquote>
<p>Here are articles to read up for further understanding:<br /><a target="_blank" href="https://qeescancode.hashnode.dev/javascript-spread-operator-simplified">JAVASCRIPT SPREAD OPERATOR SIMPLIFIED</a> by <a class="user-mention" href="https://hashnode.com/@qeesCanCode">Balqees Ibrahim</a><br /><a target="_blank" href="https://h.daily-dev-tips.com/10-ways-to-use-the-spread-operator-in-javascript">10 ways to use the spread operator in JavaScript</a> by <a class="user-mention" href="https://hashnode.com/@dailydevtips">Chris Bongers</a></p>
</blockquote>
<p>Example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> obj = {
  <span class="hljs-attr">item1</span>: <span class="hljs-string">"Books"</span>, 
  <span class="hljs-attr">item2</span>: <span class="hljs-string">"Pens"</span>
}
<span class="hljs-keyword">let</span> cloneObj = {...obj}

obj.item2 = <span class="hljs-string">"Pencil"</span>

<span class="hljs-built_in">console</span>.log(obj)
<span class="hljs-comment">// { item1: 'Books', item2: 'Pencil' }</span>
<span class="hljs-built_in">console</span>.log(cloneObj)
<span class="hljs-comment">// { item1: 'Books', item2: 'Pens' }</span>
</code></pre>
<blockquote>
<p>Using both <code>Object.assign()</code> method and the spread operator <code>...</code> are both <strong>Shallow Cloning.</strong><br />Read about Shallow Cloning here:<br /><a target="_blank" href="https://rahulism.tech/what-is-shallow-copy-in-javascript">What is Shallow Copy in JavaScript?</a> by <a class="user-mention" href="https://hashnode.com/@RAHULISM">Rahul</a></p>
<p>Shallow Cloning happens at only the first layer of the object which is cloned.</p>
</blockquote>
<ul>
<li><strong>JSON.parse() and JSON.stringify() methods</strong></li>
</ul>
<p>Making use of <code>JSON.parse()</code> and <code>JSON.stringify()</code> methods is know as <strong>Deep Cloning</strong>. This is where an object has another object as its property value and you'll like the objects to be cloned.</p>
<blockquote>
<p>Here's an article that covers the topic Deep Cloning:<br /><a target="_blank" href="https://charandev.com/deep-copy-vs-shallow-copy-in-javascript">Deep Copy vs. Shallow Copy in JavaScript</a> by <a class="user-mention" href="https://hashnode.com/@charandev">Devalla Sai Charan</a></p>
</blockquote>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> obj = {
  <span class="hljs-attr">item1</span>: <span class="hljs-string">"Books"</span>, 
  <span class="hljs-attr">item2</span>: {
    <span class="hljs-attr">item2_1</span>: <span class="hljs-string">"Pens"</span>,
    <span class="hljs-attr">item2_2</span>: <span class="hljs-string">"Marker"</span>
  }
}
<span class="hljs-keyword">let</span> cloneObj = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">JSON</span>.stringify(obj))

obj.item2.item2_1 = <span class="hljs-string">"Pencil"</span>

<span class="hljs-built_in">console</span>.log(obj)
<span class="hljs-comment">//  { </span>
<span class="hljs-comment">//    item1: 'Books', </span>
<span class="hljs-comment">//    item2: { </span>
<span class="hljs-comment">//       item2_1: 'Pencil',</span>
<span class="hljs-comment">//       item2_2: 'Marker'</span>
<span class="hljs-comment">//     }</span>
<span class="hljs-comment">//  }</span>
<span class="hljs-built_in">console</span>.log(cloneObj)
<span class="hljs-comment">// { </span>
<span class="hljs-comment">//  item1: 'Books', </span>
<span class="hljs-comment">//  item2: {</span>
<span class="hljs-comment">//    item2_1: 'Pens', </span>
<span class="hljs-comment">//    item2_2: 'Marker' </span>
<span class="hljs-comment">//  }</span>
<span class="hljs-comment">// }</span>
</code></pre>
<hr />
<p>Here are more instances of Pass by Reference to test yourself, try guessing the answer and figuring why</p>
<pre><code class="lang-js"><span class="hljs-comment">// Example 1</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">byReference</span>(<span class="hljs-params">personObj</span>) </span>{
  personObj.name = <span class="hljs-string">"John"</span>
  personObj = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Favourite"</span>, 
    <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>
  }

  <span class="hljs-keyword">return</span> personObj
}

<span class="hljs-keyword">const</span> person = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Doe"</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>
}

<span class="hljs-keyword">const</span> newPerson = byReference(person);

<span class="hljs-built_in">console</span>.log(person)
<span class="hljs-built_in">console</span>.log(newPerson)

<span class="hljs-comment">// Example 2</span>
<span class="hljs-keyword">let</span> todos = [
  {<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">title</span>: <span class="hljs-string">"Read for exam"</span>, <span class="hljs-attr">done</span>: <span class="hljs-literal">false</span>},
  {<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">title</span>: <span class="hljs-string">"Complete my article"</span>, <span class="hljs-attr">done</span>: <span class="hljs-literal">false</span>},
  {<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">title</span>: <span class="hljs-string">"Apply for Github Campus Expert before 28"</span>, <span class="hljs-attr">done</span>: <span class="hljs-literal">false</span>}
]

<span class="hljs-keyword">let</span> todo = todos.map(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (todo.id === <span class="hljs-number">1</span>) todo.done = <span class="hljs-literal">true</span>

  <span class="hljs-keyword">return</span> todo
})

<span class="hljs-built_in">console</span>.log(todo)
<span class="hljs-built_in">console</span>.log(todos)
</code></pre>
<h3 id="heading-array">Array</h3>
<p>An array is used to store similar data types and is a special object. Since it an object/special object it also follows the Passed by Reference concept.</p>
<p>Example</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> fruits = [<span class="hljs-string">"orange"</span>, <span class="hljs-string">"apple"</span>, <span class="hljs-string">"mango"</span>]
<span class="hljs-keyword">let</span> newFruits = fruits
newFruits.push(<span class="hljs-string">"pineapple"</span>)

<span class="hljs-built_in">console</span>.log(fruits)
<span class="hljs-comment">// [ 'orange', 'apple', 'mango', 'pineapple' ]</span>
<span class="hljs-built_in">console</span>.log(newFruits)
<span class="hljs-comment">// [ 'orange', 'apple', 'mango', 'pineapple' ]</span>
</code></pre>
<p>From the example above, you'll notice its similar to the <a class="post-section-overview" href="#objexp">object example</a>. Even though it's an array the same approach is carried out.</p>
<hr />
<p>Here's a video made by my friend <a target="_blank" href="https://twitter.com/R4MSE5">Olli</a>, it's all about the concept Pass by Value and Pass by Reference. I'll suggest you watch the video, the visual illustration makes the concept easier to understand if you prefer visual illustrations.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/lAjshs4yLKg">https://youtu.be/lAjshs4yLKg</a></div>
<p> </p>
<h2 id="heading-references-to-read-further">References to read further</h2>
<ul>
<li><p><a target="_blank" href="https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0">Explaining Value vs. Reference in Javascript</a></p>
</li>
<li><p><a target="_blank" href="https://hashnode.com/post/es6-objectassign-method-with-example-ck5me354b04ovqps150z8mvf1">ES6 object.assign() method with Example</a></p>
</li>
<li><p><a target="_blank" href="https://qeescancode.hashnode.dev/javascript-spread-operator-simplified">JAVASCRIPT SPREAD OPERATOR SIMPLIFIED</a></p>
</li>
<li><p><a target="_blank" href="https://h.daily-dev-tips.com/10-ways-to-use-the-spread-operator-in-javascript">10 ways to use the spread operator in JavaScript</a></p>
</li>
<li><p><a target="_blank" href="https://charandev.com/deep-copy-vs-shallow-copy-in-javascript">Deep Copy vs. Shallow Copy in JavaScript</a></p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Pass by Value and Pass by References are essential concepts one must understand if you'd like to advance your skills using JavaScript. I hope the article was helpful, please do leave comments below, if you have any questions shoot. Thanks for Reading. If you'd like to contact me, you can <a target="_blank" href="https://twitter.com/FavouriteJome1">here @favouritejome1</a>.</p>
]]></content:encoded></item></channel></rss>