<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ UI Design - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ UI Design - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 15 May 2026 09:48:07 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/ui-design/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Apply Academic Theories to Human-Centered Web Design [Full Handbook] ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever abandoned an app right at the sign‑up page? Or felt uneasy navigating a website because the buttons were scattered randomly, the colors clashed, and the layout felt confusing and unneces ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-apply-academic-theories-to-human-centered-web-design-handbook/</link>
                <guid isPermaLink="false">69fe29e9f239332df4f7cd02</guid>
                
                    <category>
                        <![CDATA[ Frontend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MathJax ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Great John ]]>
                </dc:creator>
                <pubDate>Fri, 08 May 2026 18:22:33 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/d7621fda-83a6-460e-aa38-bce970d4a655.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever abandoned an app right at the sign‑up page? Or felt uneasy navigating a website because the buttons were scattered randomly, the colors clashed, and the layout felt confusing and unnecessarily complex?</p>
<p>Maybe you were asked to complete twenty fields in one go. You carefully filled everything out, hit Submit — and only then were you told that your password didn't meet some hidden, unspoken requirement. A requirement that was never communicated upfront.</p>
<p>Instead of helpful guidance, you were met with a vague message: “Invalid input." Invalid how, you wonder?</p>
<p>Required fields weren’t marked. There was no real‑time validation. No helpful red outline showing which field was wrong. Just a generic prompt telling you to “go back and correct missing information,” as if you’re supposed to magically know what the system wants.</p>
<p>So you scroll.</p>
<p>You search.</p>
<p>You guess.</p>
<p>And you're now getting frustrated.</p>
<p>The reason you're frustrated is simple: no one enjoys repeating a task they thought they had already completed — especially when the mistakes could've been prevented with clear guidance along the way.</p>
<p>You manage to fill in the form and you tap the Submit button.</p>
<p>Nothing happens.</p>
<p>No loading spinner.</p>
<p>No subtle animation.</p>
<p>No confirmation message.</p>
<p>No success screen.</p>
<p>Just silence. For a brief moment, you’re left wondering: Did it go through? So you tap again. And maybe… one more time.</p>
<p>At this point, you become fed up and you either postpone the signup process to when you have the time, or you may not ever return.</p>
<p>Even if you haven’t experienced this exact scenario, you’ve almost certainly felt the same kind of friction: that moment when a digital interface makes you pause, hesitate, or wonder what you’re supposed to do next.</p>
<p>These frustrations often arise because frontend developers either overlook or are unaware of the essential design principles and theories that underpin a smooth, intuitive user experience.</p>
<p>As a frontend developer, your interface should minimise cognitive load, provide immediate clarity, and guide users effortlessly through every task.</p>
<p>In this handbook, I'll introduce the academic theories that should inform and elevate your frontend decisions.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-10-fittss-law">1.0 Fitts’s Law:</a></p>
<ul>
<li><p><a href="#heading-11-use-padding-wisely">1.1 Use padding wisely</a></p>
</li>
<li><p><a href="#heading-12-use-infinite-targets">1.2 Use infinite targets</a></p>
</li>
<li><p><a href="#heading-design-takeaway-from-fitts-law">Design Takeaway from Fitts Law:</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-20-hicks-law">2.0 Hick's Law:</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-hicks-law">Design Takeaway from Hick's Law</a></li>
</ul>
</li>
<li><p><a href="#heading-30-gestalt-principles">3.0 Gestalt Principles:</a></p>
<ul>
<li><p><a href="#heading-key-gestalt-principles">Key Gestalt Principles:</a></p>
</li>
<li><p><a href="#heading-31-proximity">3.1 Proximity</a></p>
</li>
<li><p><a href="#heading-32-similarity">3.2 Similarity</a></p>
</li>
<li><p><a href="#heading-33-continuity">3.3 Continuity</a></p>
</li>
<li><p><a href="#heading-34-closure">3.4 Closure</a></p>
</li>
<li><p><a href="#heading-35-figureground">3.5 Figure/Ground</a></p>
</li>
<li><p><a href="#heading-36-common-fate">3.6 Common Fate</a></p>
</li>
<li><p><a href="#heading-37-focal-point">3.7 Focal Point</a></p>
</li>
<li><p><a href="#heading-design-takeaways-from-the-gestalt-principles">Design Takeaways from the Gestalt Principles</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-40-von-restorff-effect-the-isolation-effect">4.0 Von Restorff Effect (The Isolation Effect):</a></p>
<ul>
<li><a href="#heading-design-takeway-from-von-restorff">Design takeway from Von Restorff</a></li>
</ul>
</li>
<li><p><a href="#heading-50-jakobs-law">5.0 Jakob’s Law</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-jakobs-law">Design Takeaway from Jakob's Law</a></li>
</ul>
</li>
<li><p><a href="#heading-60-millers-law">6.0 Miller’s Law</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-millers-law">Design Takeaway from Miller's Law</a></li>
</ul>
</li>
<li><p><a href="#heading-70-the-goal-gradient-hypothesis">7.0 The Goal-Gradient Hypothesis</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-goal-gradient-hypothesis">Design Takeaway from Goal-Gradient Hypothesis</a></li>
</ul>
</li>
<li><p><a href="#heading-80-zeigarnik-effect">8.0 Zeigarnik Effect</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-zeigarnik-effect">Design Takeaway from Zeigarnik Effect</a></li>
</ul>
</li>
<li><p><a href="#heading-90-teslas-law">9.0 Tesla’s Law:</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-teslas-law">Design Takeaway from Tesla's Law</a></li>
</ul>
</li>
<li><p><a href="#heading-100-peak-end-rule">10.0 Peak End Rule:</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-peak-end-rule">Design takeaway from Peak End Rule</a></li>
</ul>
</li>
<li><p><a href="#heading-110-postels-law">11.0 Postel’s Law:</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-postels-law">Design Takeaway from Postel's Law</a></li>
</ul>
</li>
<li><p><a href="#heading-120-doherty-threshold">12.0 Doherty Threshold:</a></p>
<ul>
<li><a href="#heading-design-takeaways-from-doherty-threshold">Design Takeaways from Doherty Threshold</a></li>
</ul>
</li>
<li><p><a href="#heading-130-serial-position-effect-primacy-and-recency">13.0 Serial Position Effect (Primacy and Recency):</a></p>
<ul>
<li><a href="#heading-design-takeaways-serial-position-effect">Design Takeaways Serial Position Effect</a></li>
</ul>
</li>
<li><p><a href="#heading-140-occams-razor">14.0 Occam’s Razor:</a></p>
<ul>
<li><a href="#heading-design-takeaway-from-occams-razor">Design Takeaway from Occam's Razor</a></li>
</ul>
</li>
<li><p><a href="#heading-150-parkinsons-law">15.0 Parkinson's Law</a></p>
<ul>
<li><a href="#heading-design-takeaway-for-parkinsons-law">Design Takeaway for Parkinson's law</a></li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a href="#heading-references">References</a></p>
</li>
</ul>
<p>You might wonder what academic theories have to do with frontend development.</p>
<p>The answer is simple. Academic theories aren't abstract ideas. There are the result of rigorous scientific investigation — controlled experiments, validated models, and decades of research into how humans think, learn, perceive, and interact with information.</p>
<p>Because these theories are grounded in evidence rather than opinion, they offer reliable guidance for building interfaces that align with how the human brain actually processes information.</p>
<p>Applying them to frontend development means you're not designing by guesswork or personal preference. Instead, you're applying tested, scientific insights to create clearer, faster, more humane user experiences.</p>
<p>In other words, when you build with academic theory in mind, your frontend becomes more than just visually appealing — it becomes cognitively efficient, behaviourally aligned, and measurably easier for users to navigate.</p>
<p>You can use the following laws and principles to guide your development work. Let’s start by looking at Fitt’s law.</p>
<h2 id="heading-10-fittss-law"><strong>1.0 Fitts’s Law:</strong></h2>
<p>Fitts’s law is the brainchild of Paul Fitts. He was among the early psychologists who recognised that many human errors result from flawed design rather than simple human weakness.</p>
<p>During World War II, he studied airplane cockpit layouts and concluded that numerous incidents attributed to pilot error were actually caused by poor design decisions (Hall, 2023; Budiu, 2022).</p>
<p>Here's the formula:</p>
<p>$$T = a + b \cdot \log_2\left(1 + \frac{D}{W}\right)$$</p>
<p>T = Movement Time</p>
<p>D = Distance to the target</p>
<p>W = Width (size) of the target</p>
<p>a, b = Empirically determined constants</p>
<p>Based on his findings, Fitts postulated that the time required to acquire/reach a target is determined by the distance to the target and the size of the target.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/7d2699bd-4878-4ab0-8669-21616cb8faf1.png" alt="7d2699bd-4878-4ab0-8669-21616cb8faf1" style="display:block;margin:0 auto" width="691" height="244" loading="lazy">

<p><em>Fig 1.0: Illustration of Fitts Law.</em></p>
<p>From the above, between Target B and Target C, it will be faster to interact with Target C than Target B simply because of the distance (Target B is farther away). Interestingly, though Target A and Target C are at the same distance, Target C will still be faster to interact with and less error-prone because of its larger size.</p>
<p>In simple terms, Fitt’s Law tells us that the time required to move to a target depends on two main factors: the distance to the target and the size of the target. The farther away an element is, the longer it takes to reach. The smaller it is, the more precision it demands, which increases the interaction time and the likelihood of errors.</p>
<p>Conversely, closer and larger targets reduce cognitive load, motor effort, and frustration.</p>
<p>In a nutshell, Fitts’s main message to developers is to reduce the distance users must travel on the screen and to make important buttons large and visually dominant.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/bc293949-cadc-46b2-892d-bdfa1dfc6db3.jpg" alt="bc293949-cadc-46b2-892d-bdfa1dfc6db3" style="display:block;margin:0 auto" width="928" height="664" loading="lazy">

<p><em>Fig 1.1: Showing Call-to-Action buttons are the largest and most visually prominent elements on each screen.</em></p>
<p>From the image above, you can see that the Call-to-Action buttons on each of the screens are the most visually dominant button and largest in size. They're also placed within the natural region. This makes them faster/easier to interact with.</p>
<p>You should also place your Call-to-Action button within the natural zone. This is a zone on a mobile phone where it's easy to reach with the thumb (as most people use their thumbs to select things on a phone screen). Here's a diagram showing the "natural zone" on a typical smartphone. It's much faster for a user to interact within the "natural zone" than the "hard zone" (see figure).</p>
<img src="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/e98d8d91-b4e6-4b4a-96e5-2524a6e09028.png" alt="e98d8d91-b4e6-4b4a-96e5-2524a6e09028" style="display:block;margin:0 auto" width="1536" height="1024" loading="lazy">

<p><em>Fig 1.2: Showing three different zones for buttons placement (natural, stretching and hard region)</em></p>
<h3 id="heading-11-use-padding-wisely">1.1 Use Padding Wisely</h3>
<p>Fitts' law can be applied to your development by increasing padding wisely. You can also use padding to increase the interactive area. By doing this, you're increasing the size of the targets.</p>
<p>This is important, because imagine a menu that disappears the moment your cursor drifts a few inches away. You’re weren't trying to close it — you simply moved slightly, and suddenly the entire menu collapses. That tiny slip forces you to start the interaction all over again. It’s a small mistake, but it creates a disproportionately frustrating experience.</p>
<p>This happens because the interactive area is too narrow.</p>
<p>That’s why effective padding — or more broadly, generous interactive zones — is essential. By increasing the clickable or hoverable area around a menu, you are increasing the size of the targets, which makes the interaction more stable, more forgiving, and far less cognitively demanding.</p>
<p>This ensures users can move naturally without fear of accidentally “falling off” the target.</p>
<h3 id="heading-12-use-infinite-targets">1.2 Use Infinite Targets</h3>
<p>Another fundamental principle that emerges from Fitt’s Law is the idea of infinite targets. When an interface element is placed at the very edge or corner of a screen, it becomes effectively “infinite” because the cursor can't move beyond the screen boundary. The edge acts as a physical barrier, allowing the user to fling the mouse in that direction without precision or careful aiming.</p>
<p>As a result, corners and edges become the fastest, easiest, and most reliable places for users to access important controls.</p>
<p>This is why operating systems such as Apple’s macOS and Microsoft Windows position their most essential menus and buttons at these locations. The macOS Apple Menu sits in the top‑left corner, Windows historically placed the Start button in the bottom‑left corner, and both systems anchor taskbars, docks, and notification areas along screen edges.</p>
<p>These placements reduce cognitive load, minimise motor effort, and increase interaction speed because users do not need to slow down or correct their cursor movement. The screen itself “catches” the pointer.</p>
<p>In essence, infinite targets transform small interface elements into large, easy‑to‑hit zones simply by leveraging the geometry of the screen.</p>
<p>What this means for you: place your most important and frequently used actions where users can reach them with the least effort. Screen edges and corners act as natural stopping points, meaning users can't overshoot them.</p>
<h3 id="heading-design-takeaways-from-fitts-law">Design Takeaways from Fitts Law:</h3>
<p><strong>Place Primary Actions Where the Task Ends:</strong><br>Placing a submit button at the top‑right forces users to travel all the way back after completing a long form. This increases interaction cost and breaks flow. The best place for a submit button is at the bottom of the form — exactly where the user finishes the task. This aligns with natural reading and interaction patterns.</p>
<p><strong>Keep Related Actions Physically Close:</strong><br>Separating “Add to Cart” and “Check Out” across opposite sides of the screen forces unnecessary thumb movement. Group related actions to reduce effort and speed up decisions.</p>
<p><strong>Make Primary Targets Large and Visually Dominant:</strong><br>Your main CTAs (“Subscribe Now,” “Pay Now,” “Create Account,” “Sign Up”) should be the most recognisable elements on the screen. Large, high‑contrast targets reduce errors and improve speed.</p>
<p><strong>Place High‑Value Actions at Screen Edges and Corners:</strong><br>Edges and corners act as “infinite targets” because the cursor can’t overshoot them. This makes them the fastest, easiest, and most reliable places for critical controls.</p>
<p>A tiny icon in the middle of the screen is hard to hit. The same icon placed at an edge becomes effectively huge because the boundary “catches” the pointer. Also, actions like navigation, primary CTAs, or global controls should live where users can reach them with minimal effort. Avoid burying important actions in the centre of the screen.</p>
<p><strong>Increase Target Size With Generous Padding:</strong><br>Small interactive zones force users to aim with pixel‑level precision. Adding padding expands the clickable or hoverable area, making interactions easier, faster, and more forgiving.</p>
<p><strong>Prevent Accidental “Fall‑Off” With Larger Hit Areas:</strong><br>Menus that collapse the moment the cursor drifts slightly create frustration. A wider interactive zone keeps the menu open during natural mouse movement, reducing accidental resets.</p>
<p>Users don’t move perfectly. Interfaces should accommodate slight slips without punishing them. Larger targets reduce cognitive load and eliminate unnecessary frustration. so by increasing the effective size of buttons, menus, and controls, you create interactions that feel stable and predictable, and users can move confidently without fear of losing their place.</p>
<p><strong>To Sum Up:</strong> The farther away an element is, the longer it takes to reach. The smaller it is, the more precision it demands, which increases the interaction time and the likelihood of errors. Conversely, closer and larger targets reduce cognitive load, motor effort, and frustration.</p>
<h2 id="heading-20-hicks-law"><strong>2.0 Hick's Law</strong>:</h2>
<p>Hick’s Law is a psychological principle that describes the relationship between the number of choices presented to a user and the time it takes them to make a decision. It was formulated by William Edmund Hick in 1952 (Yablonski, 2022; Proctor &amp; Scheider, 2018).</p>
<p>The law states that as the number of options increases, the decision time increases logarithmically. In simple terms, more choices slow users down, while fewer choices speed up decision-making.</p>
<p>$$T = a + b \cdot \log_2(n + 1)$$</p>
<p>Where:</p>
<p>T = time to make a decision,</p>
<p>n = number of choices,</p>
<p>b= a constant that depends on the task and the individual</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/d2c45f4b-77e9-42dc-a9c3-165dfe5f7ce7.jpg" alt="d2c45f4b-77e9-42dc-a9c3-165dfe5f7ce7" style="display:block;margin:0 auto" width="1136" height="692" loading="lazy">

<p><em>Figure 2.0 illustrates the relationship between user experience, reaction time, and the number of actions.</em></p>
<p>This is how users feel, for example, when they encounter a form that asks for too much information upfront. The longer the form gets, the more frustrated they become.</p>
<p>Examples of this are overloading menus with too many items, presenting long, unorganised forms, giving too many calls-to-action on one screen, and building nested menus with excessive depth.</p>
<p>All of these create friction and can lead to cognitive overload.</p>
<h3 id="heading-design-takeaway-from-hicks-law">Design Takeaway from Hick's Law</h3>
<p><strong>Avoid Overloading Users With Too Many Actions:</strong><br>Too many buttons, menu items, or choices at once increases cognitive load and slows decision‑making. Users freeze when everything competes for attention.</p>
<p><strong>Keep Navigation Clean and Focused:</strong><br>Cluttered menus hurt both usability and SEO. Search engines struggle to track overly complex navigation structures, and users struggle to find what matters.</p>
<p><strong>Use Progressive Disclosure to Reduce Complexity:</strong><br>Hide advanced or rarely used options under “More” or expandable sections. Reveal complexity only when the user needs it.</p>
<p><strong>Break Complex Tasks Into Smaller, Manageable Steps:</strong><br>Progressive disclosure works beautifully for multi‑step forms and decision flows. Smaller steps reduce overwhelm and improve completion rates.</p>
<p><strong>Group Related Options Into Logical Categories:</strong><br>Organising actions into meaningful clusters helps users process information faster. For example, placing “Edit” and “Delete” together leverages natural mental grouping.</p>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/mbYIfRxSkHs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p><em>Video 2.0: Video description of Progressive Disclosure.</em></p>
<p>From the video above, instead of showing all the menu details at once, it is better to hide them initially. As you can see, the additional information only appears when the arrow down button is pressed. This approach prevents overwhelming the user and keeps the interface clean and focused.</p>
<p>You should also reduce decision anxiety, as too many choices create doubt and friction (as they say, the more you ask from a user, the less you get).</p>
<p>Beyond this, try to use recommended labels, show brief descriptions, provide visual previews, and use comparison tables wisely to show comparison between products especially when they have many characteristics. An example of a comparison table is shown below:</p>
<p><a href="https://drive.google.com/file/d/1sY-tb9W1QDnyrH9dd3NSYsteP9WoMT27/view?usp=drive_link"><img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/5e52527a-3faf-4da1-97c2-a2a09ca7af8b.jpg" alt="Use of comparison table to compare products" style="display:block;margin:0 auto" width="1038" height="972" loading="lazy"></a></p>
<p><em>Figure 2.1: A comparison table being used to simplify complex information.</em></p>
<p>Also, rather than showing advanced configuration options by default, display only the most commonly used settings. Advanced options can be hidden under an expandable section like “Advanced” or “More Settings. This makes your interface less cluttered and more visually organized.</p>
<p>And speaking of visual organization, this is the perfect moment to introduce Gestalt principles — the psychological rules that explain how users naturally group and interpret what they see.</p>
<p><strong>To Sum Up</strong>: As the number of options increases, the decision time increases logarithmically.</p>
<h2 id="heading-30-gestalt-principles"><strong>3.0 Gestalt Principles</strong>:</h2>
<p>In the 1920s, a group of German psychologists – Max Wertheimer, Kurt Koffka, and Wolfgang Köhlern – introduced what are now known as the Gestalt Principles. Their work sought to understand how humans perceive and interpret visual information (Bustamante, 2023).</p>
<p>The word “Gestalt” is German for “unified whole,” reflecting the core idea behind the theory: people naturally perceive objects as organised patterns and complete forms rather than as separate, disconnected parts.</p>
<p>These principles explain how the human mind structures visual elements to make sense of the world. Over time, they have become highly influential in fields such as design, user experience (UX), psychology, and data visualization, where understanding perception is critical.</p>
<h3 id="heading-key-gestalt-principles">Key Gestalt Principles:</h3>
<h3 id="heading-31-proximity">3.1 Proximity</h3>
<p>Elements that are placed close to each other are perceived as a group, while those spaced far apart are seen as separate. This is why labels are placed directly next to their corresponding input fields.</p>
<p>For example: In a blog feed, the "Title," "Author," and "Date" should have small margins between them (8px), while the space between one blog post card and the next should be much larger (40px). This tells the user's brain: "These three text strings belong to this specific post."</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/b68ab7f4-1b2e-47f1-8e8c-8ae8f32198c1.jpg" alt="b68ab7f4-1b2e-47f1-8e8c-8ae8f32198c1" style="display:block;margin:0 auto" width="1046" height="956" loading="lazy">

<p><em>Fig 3:0 Illustration of proximity (Gestalt Principle)</em></p>
<p>From the fig above, the spacing within the blog feed plays a powerful role in how effortlessly users interpret what they see. When elements sit close together, the brain instinctively treats them as belonging to the same unit. This is why placing the author credit just 8px beneath the title creates an immediate mental link. The viewer doesn’t need to pause or decode who wrote which article; proximity does the cognitive work automatically, forming a tight, intuitive grouping.</p>
<p>Equally important is the generous 40px gap between individual cards. This larger spacing introduces “visual breathing room.” Without it, a feed can quickly collapse into a dense wall of text, overwhelming the user and discouraging exploration. The wider margin establishes a clear boundary—a natural stop-and-start rhythm—that makes each card feel distinct and the entire layout more scannable.</p>
<p>Finally, subtle spacing differences can guide behaviour, not just perception. The slightly larger 12px margin above the read‑more link separates it from the passive information above it. This spacing cues the user that the link represents an action rather than another piece of descriptive text. It’s a small adjustment, but it shifts the element’s role from informational to interactive, helping users understand what they can <em>do</em> next.</p>
<p>Together, these spacing decisions transform a simple list of posts into a structured, intuitive, and behaviourally clear interface—one where the user never has to think about the layout, because the layout is already thinking for them.</p>
<p>Proximity controls meaning: move elements closer to show connection, separate them to show difference.</p>
<h3 id="heading-32-similarity">3.2 Similarity</h3>
<p>We naturally group elements that share similar visual characteristics, such as color, shape, size, or orientation.</p>
<p>For example, even if buttons are spread across a page, if they're all the same shade of blue, the user understands they perform similar functions.</p>
<p>If your primary "Submit" button is blue with rounded corners, every other primary action on your site should look exactly the same. If you suddenly use a square red button for a primary action, the user will be confused because the "similarity" is broken.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/151d9658-5a4b-4d1d-b885-02c73c53cdbd.jpg" alt="151d9658-5a4b-4d1d-b885-02c73c53cdbd" style="display:block;margin:0 auto" width="1618" height="2170" loading="lazy">

<p><em>Fig 3:1 : illustration of similarity (Gestalt principle)</em></p>
<p>As you can see from above, the layout clearly demonstrates how the Gestalt Principle of Similarity works by showing two different visual situations: one where everything matches, and one where a single element breaks the pattern.</p>
<p>All three product cards share the same visual characteristics:</p>
<ul>
<li><p>Same card shape</p>
</li>
<li><p>Same border and shadow</p>
</li>
<li><p>Same image size and placement</p>
</li>
<li><p>Same blue “Add to Cart” button</p>
</li>
<li><p>Same font style and spacing</p>
</li>
</ul>
<p>Because these elements look alike, your brain automatically groups them as one category — “products that belong together.”<br>You don’t have to think about it; the similarity creates instant visual unity.</p>
<p>This is the Gestalt Principle of Similarity in action.</p>
<p>In the second row, everything is still similar except one button:</p>
<ul>
<li><p>The middle product’s button is orange, not blue</p>
</li>
<li><p>It has square corners, not rounded</p>
</li>
<li><p>The text is italic, not regular</p>
</li>
<li><p>The label changes to “Quick Buy”</p>
</li>
</ul>
<p>Because this button breaks the shared pattern, your brain immediately notices it and treats it as different or special.</p>
<p>Developers can use broken similarity to intentionally highlight featured items, promotions, or urgent actions.</p>
<p>When similarity is broken, the different element stands out and draws attention.</p>
<h3 id="heading-33-continuity">3.3 Continuity</h3>
<p>The human eye prefers to follow a continuous path or curve rather than jagged or broken lines. We perceive items aligned on a line or curve as being related. This is often used in navigation menus or horizontal carousels to guide the user's gaze.</p>
<p>For example, you might have a horizontal carousel where the last visible card is slightly "cut off" at the edge of the screen. This visual break creates a path that encourages the user to keep scrolling as their eyes follow the line of cards.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/e44556e8-4174-4073-9c05-63b5df9a1278.jpg" alt="e44556e8-4174-4073-9c05-63b5df9a1278" style="display:block;margin:0 auto" width="1650" height="214" loading="lazy">

<p><em>Fig 3:2: illustration of continuity (Gestalt principle)</em></p>
<p>As you can see, all four form fields — <em>First Name</em>, <em>Last Name</em>, <em>Email Address</em>, and <em>Phone Number</em> — are perfectly aligned along one continuous horizontal path. Because the human eye naturally prefers to follow an unbroken line, your gaze moves smoothly from left to right across the fields without effort.</p>
<p>The final field is slightly cut off at the edge, which creates a subtle visual cue that the line continues beyond the visible area. This encourages the user to keep scrolling or swiping, because their eyes are already following the direction of the form.<br>when elements are arranged along a straight path, curve, or flow, the brain automatically treats them as connected and expects the pattern to continue.</p>
<p>Another example is Instagram Stories, which are arranged in a smooth horizontal line at the top of the app. Instagram reinforces this by slightly revealing the next story circle at the edge of the screen. That tiny “peek” acts as a continuation cue — your eyes expect the line to keep going, so your finger follows.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/bb019a6d-33c9-4509-b1c7-191b5a453c46.jpg" alt="bb019a6d-33c9-4509-b1c7-191b5a453c46" style="display:block;margin:0 auto" width="1320" height="520" loading="lazy">

<p><em>Fig 3:3: illustration of continuity (Gestalt principle)</em></p>
<p>As you can see from above, all the circular story icons are arranged in a straight horizontal line, and your visual system instinctively follows that line from left to right without effort.</p>
<p>The slight visibility of the next story at the edge of the screen strengthens this effect, signaling that the sequence continues beyond what's currently shown. Also, because the icons share the same size, spacing, and shape, there are no visual interruptions, allowing your eyes to glide across them in one continuous motion.</p>
<p>This seamless flow is exactly what continuity describes: the tendency of the human eye to follow the direction of a line or pattern, assuming it continues even when part of it is out of view.</p>
<p>Continuity is the tendency of the human eye to follow the direction of a line or pattern, assuming it continues even when part of it is out of view.</p>
<h3 id="heading-34-closure">3.4 Closure</h3>
<p>Closure refers to the mind’s ability to perceive a complete, unified form even when parts of that form are missing. Rather than requiring every boundary, line, or shape to be explicitly drawn, the brain instinctively fills in the gaps. When used intentionally, closure allows interfaces to feel cleaner, more elegant, and more cognitively efficient.</p>
<p>When we look at a complex arrangement of visual elements, we tend to look for a single, recognisable pattern. If an image is missing parts, our brains fill in the gaps to "close" the shape.</p>
<p>One of the most celebrated examples of closure in visual identity design is the panda symbol used by the World Wide Fund for Nature (WWF). This logo demonstrates how strategic omission can produce a memorable, emotionally resonant, and universally recognisable mark.</p>
<p>At first glance, the panda illustration appears simple, composed of a few bold black shapes arranged against a white background.</p>
<p>Yet a closer look reveals that the panda is not fully drawn. There are no outlines defining the body, no complete contours around the head, and no explicit boundaries separating limbs from background. Instead, the designer uses a series of carefully placed shapes (ears, eye patches, nose, and partial limbs) to imply the rest of the animal. The viewer’s mind fills in the missing information, completing the silhouette effortlessly.</p>
<p>This is closure at its most effective: the brain constructs a whole from fragments, creating a sense of completeness without visual overload.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/0c40effd-e4d2-4669-af1d-56faac976b4a.jpg" alt="0c40effd-e4d2-4669-af1d-56faac976b4a" style="display:block;margin:0 auto" width="522" height="784" loading="lazy">

<p><em>Fig 3:4: illustration of closure (Gestalt principle)</em></p>
<p>For example, a "hamburger menu" (three lines) isn't a literal drawer, but our brains "close" the shape to understand it represents a menu.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/b67253cd-2a2c-4565-9818-f5586dad6d36.jpg" alt="b67253cd-2a2c-4565-9818-f5586dad6d36" style="display:block;margin:0 auto" width="1244" height="236" loading="lazy">

<p><em>Fig 3:5: illustration of closure (Gestalt principle)</em></p>
<p>An example of closure in practice can be seen in step indicators commonly used in checkout flows. These components often rely on partial shapes, implied boundaries, and incomplete outlines to guide the user through a sequence of actions.</p>
<p>For instance, upcoming steps may be represented by dashed circles. Although the circles aren't fully drawn, the viewer immediately recognises them as complete shapes. The brain resolves the missing segments, allowing the interface to communicate progression without heavy borders or fully rendered icons. This subtle use of closure reduces visual clutter while preserving clarity.</p>
<p>Closure refers to the mind’s ability to perceive a complete, unified form even when parts of that form are missing.</p>
<h3 id="heading-35-figureground">3.5 Figure/Ground</h3>
<p>This principle describes the mind's tendency to separate an object (the figure) from its surrounding area (the ground or background). In web design, using a "modal" or "pop-up" relies on this: by blurring the background, you force the user to see the pop-up as the focal figure.</p>
<p>When a user clicks "Login" on a modal/lightbox, the background site often dims (the "Ground") while the login box stays bright and centered (the "Figure"). This immediate depth change tells the user exactly where their attention belongs.</p>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/UCdjymjASOU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p><em>Video 3.5.0 Video description of Figure/Ground (Gestalt Principle)</em></p>
<p>From the video above, you can see that when the Quick View button is clicked, the selected figure stands out while the background darkens. This contrast guides the user’s attention and helps them focus on the figure. Developers can use this technique to direct users’ attention to what matters most or to what they want users to notice.</p>
<p>This principle describes the mind's tendency to separate an object (the figure) from its surrounding area (the ground or background).</p>
<h3 id="heading-36-common-fate">3.6 Common Fate</h3>
<p>Elements that move in the same direction are perceived as more related than elements that are stationary or move in different directions. Think of a dropdown menu: when all sub-items slide down together, they are clearly part of the same "unit."</p>
<p>For example, when you click a FAQ header and five sub-items slide down at the exact same speed and direction, the "Common Fate" tells the user that all those items belong to that specific category. If they flew in from different directions, the relationship would be lost.</p>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/T10xmlne6E4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p><em>Video 3.6.1 Video description of common fate (Gestalt Principle)</em></p>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/5FncGLRy0bM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p><em>Video 3.6.2 Video description of common fate (Gestalt Principle)</em></p>
<p>From the video shown above, the e‑commerce animation example demonstrates these principles clearly by using two distinct motion patterns: a group of regular products that move upward together, and a pair of special‑category items that enter dramatically from the left. Through these contrasting movements, the interface communicates category differences without relying on text labels or explicit instructions.</p>
<p>Therefore, developers can use this motion‑based differentiation as a design strategy to guide users’ perception—allowing the interface to signal hierarchy, category structure, and product importance purely through animated behaviour rather than through static visual labels.</p>
<p>Elements that move in the same direction are perceived as more related than elements that are stationary or move in different directions.</p>
<h3 id="heading-37-focal-point">3.7 Focal Point</h3>
<p>Whatever stands out visually will capture and hold the viewer’s attention first. This is essentially the principle of emphasis. A bright "Sign Up" button in a sea of gray text acts as the focal point, directing the user's primary action.</p>
<p>For example, an alert banner or a pricing table should stand out from its surroundings. Beyond this, in a three-tier pricing table (Basic, Pro, Enterprise), the "Pro" column is often slightly larger or a different color. This creates a focal point that draws the eye to the "recommended" option immediately.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/711c9ee9-b546-4041-bf86-30c80154bd47.jpg" alt="711c9ee9-b546-4041-bf86-30c80154bd47" style="display:block;margin:0 auto" width="1784" height="646" loading="lazy">

<p><em>Fig 3:7: illustration of closure (Gestalt principle)</em></p>
<p>In visual interface design, the Gestalt principle of Focal Point plays a crucial role in directing user attention toward the most important element on a screen.</p>
<p>A focal point is created when one element breaks the established pattern of surrounding elements, making it stand out immediately.</p>
<p>In e‑commerce interfaces, this principle is often applied to highlight primary actions such as purchasing, subscribing, or upgrading. The “Buy Now” button provides a clear and practical example of how focal points function within a layout.</p>
<p>From the example above, the first two buttons share the same visual characteristics: neutral colours, and regular weight text. This repetition establishes a visual pattern that the user quickly becomes familiar with.</p>
<p>But the “Buy Now” button intentionally disrupts this pattern. It uses a bright colour, which contrasts sharply with the muted tones of the other buttons. This colour difference alone is enough to draw the eye, as humans are naturally sensitive to changes in hue and saturation within a uniform environment.</p>
<p>The Focal Point may sound like it's similar to the principle of Similarity, but the two operate in completely opposite ways within perceptual psychology.</p>
<p>Similarity explains how the mind naturally groups elements that share visual characteristics –&nbsp;such as colour, shape, or size – into coherent units. Once this grouping is established, the interface gains structure and predictability.</p>
<p>Focal Point, on the other hand, works by intentionally breaking that structure. Instead of reinforcing uniformity, it introduces a deliberate contrast – through colour, scale, brightness, or motion –&nbsp;to draw the viewer’s attention to one specific element.</p>
<p>In other words, Similarity creates the background pattern, while Focal Point identifies the one element that must stand out against that pattern.</p>
<p>Whatever stands out visually will capture and hold the viewer’s attention first.</p>
<h3 id="heading-design-takeaways-from-the-gestalt-principles">Design Takeaways from the Gestalt Principles</h3>
<p><strong>Use Spacing as Your Primary Grouping Tool:</strong><br>Elements that belong together should sit closer to each other than to anything else. Spacing communicates structure faster than borders or boxes. Use tight internal spacing (6–12px) for related items and wide external spacing (24–48px) to separate groups.</p>
<p><strong>Build a Strict, Consistent Visual System — and Stick to It:</strong><br>Define clear rules for button types, text styles, icon sizes, and alignment patterns. Consistent left‑aligned text blocks, predictable carousel lines, and stable flow patterns reduce cognitive load and make interfaces feel trustworthy.</p>
<p><strong>Guide the Brain With Spacing, Alignment, Consistency, Contrast, and Motion:</strong><br>The human brain is always trying to group, follow, and prioritise what it sees. Your job is to guide that instinct through intentional layout decisions, not fight against it.</p>
<h2 id="heading-40-von-restorff-effect-the-isolation-effect"><strong>4.0 Von Restorff Effect (The Isolation Effect)</strong>:</h2>
<p>This is the brainchild of Hedwig von Restorff, posited in 1933. In principle it states: An item that stands out is more noticable and more likely to be remembered than other items (Hunt, 1995).</p>
<p>So unique or visually distinct elements grab attention and are more memorable – in other words, distinctiveness dictates memory. When a user interacts with an interface, their brain naturally seeks patterns to minimize cognitive effort.</p>
<p>While consistency is generally a virtue in design, a perfectly uniform layout can lead to "banner blindness" or habituation, where the user stops noticing details.</p>
<p>By strategically breaking a pattern through changes in color, size, shape, or spacing, the developer can "isolate" an element, triggering a biological response that flags the item as high-priority.</p>
<p>Note that although the Focal Point principle may initially seem similar to the Von Restorff Effect, they describe two different psychological processes.</p>
<p>Focal Point is a Gestalt visual principle that explains how one element becomes the centre of attention within a composition because it carries the strongest visual contrast –&nbsp;through size, colour, brightness, position, or motion. Its purpose is to guide the viewer’s eye toward the most important element in the layout.</p>
<p>The Von Restorff Effect comes from cognitive psychology, not Gestalt theory. It states that an item that is noticeably different from a group of similar items is not only more attention‑grabbing but also more memorable.</p>
<p>So Focal Point is about where the eye goes first, while the Von Restorff Effect is about what the brain remembers later.</p>
<h3 id="heading-design-takeaways-from-von-restorff">Design takeaways from Von Restorff</h3>
<p><strong>Use Isolation to Make CTAs Impossible to Miss:</strong><br>On a page filled with neutral text and standard links, a single high‑contrast button (like a bold “Primary Blue” or “Emergency Red”) instantly becomes the standout element. This leverages the Von Restorff Effect to pull the user’s eye toward the most important action.</p>
<p><strong>Create a Visual “Hitch” in the Scan Path:</strong><br>A distinct CTA interrupts the user’s natural left‑to‑right, top‑to‑bottom scanning rhythm. This makes actions like “Buy Now” or “Sign Up” the first thing they notice and the last thing they forget.</p>
<p><strong>Make Critical Actions Visually Distinct:</strong><br>Because users naturally notice the one element that breaks a pattern, your most important actions should use deliberate contrast — color, size, shape, weight, or motion. Isolate key information instead of letting it blend into surrounding UI noise.</p>
<p><strong>Avoid Over‑Differentiation — or Nothing Stands Out:</strong> If every button is loud, animated, or uniquely styled, the interface becomes chaotic. The Von Restorff Effect only works when there is a clear, stable pattern — and you break it once, intentionally.</p>
<p><strong>To Sum Up:</strong> An item that stands out is more noticable and more likely to be remembered than other items.</p>
<h2 id="heading-50-jakobs-law"><strong>5.0 Jakob’s Law</strong></h2>
<p>Jakob’s Law states that users spend most of their time on other sites, so they expect your interface to behave like the ones they already know.</p>
<p>Familiar patterns — hamburger menus, top navigation, search icons, and clickable top‑left logos — reduce cognitive load because users don’t have to interpret anything new.</p>
<p>But while Jakob’s Law is foundational to UX, I think it can also unintentionally suppress innovation.</p>
<p>When developers over‑prioritise familiarity, they fall into a standardisation trap: endlessly optimising conventional patterns instead of exploring fundamentally better ones.</p>
<p>The Pie Menu is a perfect illustration of this. According to Fitts’s Law, the time required to reach a target depends on its distance and size. Linear menus place the last item much farther from the cursor than the first, creating uneven interaction costs.</p>
<p>Radial menus position every option at an equal distance from the centre, and their wedge‑shaped targets effectively grow larger as the pointer moves outward.</p>
<p>Mathematically, pie/radial menu are faster to interact with and more efficient — yet they remain rare in mainstream web design because they violate users’ expectations. In other words, Jakob’s Law keeps us locked into a familiar but suboptimal pattern simply because “that’s how it’s always been done.”</p>
<p>But the challenge is not choosing between familiarity and innovation, but balancing them.</p>
<p>This is where the Aesthetic–Usability Effect becomes powerful. Research shows that users perceive attractive interfaces as easier to use, and they are more forgiving of minor usability friction when the design is visually pleasing.</p>
<p>A beautifully crafted Pie Menu, for example, can encourage users to invest the small amount of learning required to use it. By applying aesthetic delight strategically, developers can introduce innovative patterns without overwhelming users.</p>
<p>The principle that emerges is simple: Be conventional where it matters, and innovative where it delights.</p>
<h3 id="heading-design-takeaway-from-jakobs-law">Design Takeaway from Jakob's Law</h3>
<p><strong>Keep Trust‑Critical Elements Predictable:</strong><br>Navigation, search, authentication, and other high‑stakes interactions must follow established conventions. Users rely on these patterns for speed, confidence, and safety — this is where Jakob’s Law should be respected without exception.</p>
<p><strong>Experiment Only in Low‑Risk, High‑Creativity Areas:</strong><br>In creative or productivity‑focused zones — like editing tools in a photo app — you can safely introduce new interaction models such as radial menus, gesture wheels, or context‑aware tool selectors. These areas invite exploration and benefit from efficiency‑driven innovation.</p>
<p><strong>To Sum Up:</strong> Be conventional where it matters, and innovative where it delights.</p>
<h2 id="heading-60-millers-law"><strong>6.0 Miller’s Law</strong></h2>
<p>Miller’s Law originates from George A. Miller’s classic paper “The Magical Number Seven, Plus or Minus Two.” It states that the average person can hold only about 7 (±2) chunks of information in working memory at any given moment (Miller, 1956).</p>
<p>Crucially, Miller emphasised that the brain doesn’t store isolated items — it groups them into meaningful units called chunks. Because working memory is so limited, developers must structure information in ways that respect this cognitive boundary.</p>
<p>This principle has direct implications for interface design. Long, unbroken strings of information overwhelm users, whereas chunked formats are far easier to process.</p>
<p>For example, instead of displaying a phone number as 1234567890, formatting it as 123‑456‑7890 transforms ten digits into three manageable chunks. The same logic applies to navigation: aim for five to nine primary menu items, and if you need more, group them into categories. Users remember the category as a single chunk rather than each individual link.</p>
<p>Miller’s Law also explains why long forms are so intimidating. When a user sees 30 fields on one page, their brain interprets it as a single, massive task — far beyond the 7±2 limit.</p>
<p>A progressive stepper solves this by breaking the form into smaller stages of 5–7 fields each. This reduces cognitive load, creates a sense of progress, and significantly lowers abandonment rates.</p>
<p>The same principle applies to product listings or search results. Expecting users to compare 50 items at once is unrealistic. Instead, provide strong filtering tools so users can narrow the set to a manageable size — ideally within the range their working memory can meaningfully evaluate.</p>
<p>In essence, Miller’s Law reminds developers that humans don’t process information in bulk. They process it in structured, meaningful chunks.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6998def93dc17c4862075045/3add2891-c6f8-4df1-a044-6cea6c5f1945.jpg" alt="Image of progressive stepper" style="display:block;margin:0 auto" width="818" height="960" loading="lazy">

<p><em>Fig 6.0: Illustrating progressive stepper</em></p>
<p>In the example above, the interface uses both a progress bar and a stepper to guide the user through multiple stages of a task. After completing the first page and selecting “Continue,” the user moves to the next step, and the progress bar updates accordingly. This creates a clear sense of forward movement and accomplishment.</p>
<p>By breaking the process into smaller segments, the interface prevents cognitive overload. If all the information were presented on a single page, users might feel overwhelmed, unsure where to begin, or discouraged by the sheer volume of work.</p>
<p>A step‑by‑step flow transforms a large task into a sequence of manageable actions, increasing the likelihood of completion.</p>
<h3 id="heading-design-takeaway-from-millers-law">Design Takeaway from Miller's Law</h3>
<p><strong>Respect the 7±2 Working‑Memory Limit:</strong><br>Users can only hold about seven chunks of information at once. Long, unbroken content overwhelms them, while chunked information is instantly easier to process.</p>
<p><strong>Chunk Information Into Meaningful Units:</strong><br>The brain doesn’t store isolated items — it groups them. Format data (like phone numbers), menus, and settings into clear, memorable chunks instead of long, flat lists.</p>
<p><strong>Keep Navigation Within 5–9 Primary Items:</strong><br>If you need more than nine options, group them into categories. Users remember the category as a single chunk, not each individual link.</p>
<p><strong>Break Long Forms Into Smaller Steps:</strong><br>A 30‑field form feels like one giant task. A progressive stepper with 5–7 fields per step keeps users below the cognitive overload threshold and dramatically reduces abandonment.</p>
<p><strong>Reduce Comparison Load With Strong Filters:</strong><br>Expecting users to compare 50 products at once is unrealistic. Provide filtering tools that shrink the decision set to something the working memory can actually handle.</p>
<p><strong>Design for Chunked Thinking, Not Bulk Processing:</strong><br>Humans don’t process information in bulk — they process structured, meaningful groups. Interfaces that respect this limitation feel lighter, faster, and more intuitive.</p>
<p><strong>To Sum Up:</strong> A step‑by‑step flow transforms a large task into a sequence of manageable actions, increasing the likelihood of completion.</p>
<h2 id="heading-70-the-goal-gradient-hypothesis">7.0 The Goal-Gradient Hypothesis</h2>
<p>This is the perfect moment to introduce the Goal‑Gradient Hypothesis, originally proposed by behaviorist Clark Hull in 1932 (Yablonski, 2022). The hypothesis states that people become more motivated as they get closer to achieving a goal. In other words, users naturally accelerate their engagement when they sense they are nearing completion.</p>
<p>This principle is incredibly powerful in UX design, especially for progress tracking, gamification, and reward systems.</p>
<p>The takeaway is straightforward: Because users are more motivated near the finish line, progress indicators should be prominent and meaningful.</p>
<p>Percentages, progress bars, and step counters reinforce momentum. Micro‑achievements — such as badges, checkmarks, or subtle confetti — amplify motivation by celebrating small wins.</p>
<p>Tasks should be broken into measurable milestones so users can see themselves advancing.</p>
<p>This is why e‑learning platforms display messages like “You’ve completed 8 of 10 lessons — almost there!” and why fitness apps highlight progress with prompts such as “3 km done, 2 km to go.” These cues leverage the goal‑gradient effect to keep users engaged, energized, and eager to finish.</p>
<p>By combining progressive steppers with clear progress feedback, developers create interfaces that feel lighter, more encouraging, and far more motivating — ultimately improving completion rates and overall user satisfaction.</p>
<p>But what happens when a goal isn't completed? Why do we sometimes feel uncomfortable leaving things unfinished? That discomfort is explained by another psychological principle called the Zeigarnik Effect — the tendency for people to remember and feel tension about incomplete tasks. We will look at this next.</p>
<h3 id="heading-design-takeaway-from-goal-gradient-hypothesis">Design Takeaway from Goal-Gradient Hypothesis</h3>
<p><strong>Make Progress Visible to Boost Motivation:</strong><br>According to the Goal‑Gradient Hypothesis, users naturally speed up as they sense they’re nearing completion. Prominent progress bars, percentages, and step counters tap into this instinct and keep momentum high.</p>
<p><strong>Celebrate Micro‑Achievements to Reinforce Engagement:</strong><br>Badges, checkmarks, subtle confetti, and “step completed” cues reward small wins. These micro‑rewards amplify motivation and make long tasks feel lighter and more achievable.</p>
<p><strong>Break Tasks Into Measurable Milestones:</strong><br>Users stay motivated when they can see themselves advancing. Divide complex flows into clear steps so progress feels tangible rather than overwhelming.</p>
<p><strong>Use Progress Feedback to Drive Completion:</strong><br>Messages like “8 of 10 lessons completed — almost there” or “3 km done, 2 km to go” leverage the goal‑gradient effect to energise users and pull them toward the finish line.</p>
<p><strong>Combine Steppers With Clear Feedback for Maximum Impact:</strong><br>Progressive steppers paired with strong visual feedback create interfaces that feel encouraging, structured, and motivating — dramatically improving completion rates.</p>
<div class="embed-wrapper"><iframe width="560" height="315" src="https://www.youtube.com/embed/-mDuFB3W2bg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>

<p><em>Video 8.0 : Video illustrating goal gradient</em></p>
<p><strong>To Sum Up:</strong> People become more motivated as they get closer to achieving a goal.</p>
<h2 id="heading-80-zeigarnik-effect"><strong>8.0 Zeigarnik Effect</strong></h2>
<p>The Zeigarnik Effect is a psychological principle stating that people remember unfinished or interrupted tasks better than completed ones (Cherry, 2024).</p>
<p>Memory begins with sensory input, which is processed into short-term memory. Unfinished tasks persist in our thoughts, leading to active recall. This ongoing engagement can turn them into long-term memories, enhancing recall until resolved. This increases engagement, encourages task completion, improves retention, and drives conversions.</p>
<p>So because people remember unfinished tasks better than completed ones (Zeigarnik Effect), developers use progress indicators to make users aware that something is incomplete and motivate them to finish it.</p>
<p>In your designs, you can break long forms into multi-step processes to encourage completion and display profile completion percentages (for example, 70% complete) to push users toward 100%.</p>
<p>This is the main reason why e-commerce platforms send abandoned cart reminders to bring users back to complete their purchases. It's also why apps use streak systems to encourage daily engagement and habit formation and learning platforms show course completion bars to motivate users to finish modules.</p>
<h3 id="heading-design-takeaway-from-zeigarnik-effect">Design Takeaway from Zeigarnik Effect</h3>
<p><strong>Unfinished Tasks Stay Active in Memory — Use That to Drive Completion:</strong><br>Because incomplete tasks linger in working memory (Zeigarnik Effect), users naturally keep thinking about what they haven’t finished. This tension boosts recall, engagement, and the likelihood of returning to complete the task.</p>
<p><strong>Make Incompleteness Visible With Progress Indicators:</strong><br>Progress bars, percentages, and step counters remind users that something is still unfinished. This gentle psychological pressure motivates them to continue until the task is complete.</p>
<p><strong>Break Long Flows Into Multi‑Step Processes:</strong><br>A massive form feels overwhelming, but a stepper with smaller chunks keeps users moving. Showing “70% complete” nudges them toward finishing the last stretch.</p>
<p><strong>Use Reminders to Re‑activate Unfinished Intent:</strong><br>Abandoned cart emails, streak reminders, and “continue your lesson” prompts work because the unfinished task is already active in the user’s mind. The reminder simply pulls them back into the loop.</p>
<p><strong>Celebrate Completion to Close the Cognitive Loop:</strong><br>Checkmarks, confirmations, and completion badges give users closure. This resolves the mental tension created by the unfinished task and reinforces positive behaviour.</p>
<p><strong>To Sum Up:</strong> Unfinished tasks persist in our thoughts, leading to active recall.</p>
<h2 id="heading-90-teslers-law"><strong>9.0 Tesler’s Law</strong>:</h2>
<p>This law was proposed by Lawrence Tesler. He was a computer scientist known for his work on human-computer interaction, and he contributed significantly to making software more user-friendly, including work on cut, copy, and paste functionality.</p>
<p>This law is otherwise known as the Law of Conservation of Complexity. The core Idea here is every process has a certain amount of “inherent complexity" that can't be removed. You can only decide who handles it: the user or the system.</p>
<p>Some examples of these inherent complexities might be:</p>
<ul>
<li><p>translating user actions into correct operations behind the scenes,</p>
</li>
<li><p>handling unreliable or slow network connections,</p>
</li>
<li><p>connecting with third-party APIs, services, or legacy systems,</p>
</li>
<li><p>sorting large datasets quickly,</p>
</li>
<li><p>performing complex search operations</p>
</li>
<li><p>managing version changes and compatibility issues,</p>
</li>
<li><p>managing state, interactions, and animations without confusing the user.</p>
</li>
</ul>
<p>All of these can be inherently complex, but it's the job of the developer to deal with the complexity.</p>
<p>As a developer, you should always try as much as possible to push complexity to the system. For example, instead of making a user type their full address manually, use an Auto-complete API (Google’s Places and Map is best for this). The complexity of finding and validating the address still exists, but the software handles the work for them.</p>
<p>Here's a practical example: let’s say you're designing a student platform that requires users to enter their university name. A practical approach would be to store an array of all universities in the UK in your codebase (This is the hard part Tesla hinted at).</p>
<p>As the user types, they don't need to enter the full name, and their full university name is shown (relating to what they have typed). For instance, if they intend to type “University of Sheffield,” simply typing “Sheff” should prompt the system to display the full university name, which they can then select.</p>
<p>In Dart, you can use a package like fuzzysearch to implement this kind of intelligent matching.</p>
<p>The advantage of this approach is greater than it first appears. It improves data consistency because users often enter the same information in different ways. For example, some users might type “Uni of Sheff,” others “Sheffield University,” and others “Uni of Sheffield,” while all are referring to “University of Sheffield.”</p>
<p>This is how messy data is created, and it creates more work for data analysts. Little wonder that data analysts spend up to 70% of their time cleaning data.</p>
<p>If developers invested more time in structuring how data is collected to ensure consistency, there would be far less work downstream for analysts. This same logic should be applied in how we collect date, time, and other information.</p>
<p>So apart from people's names and email addresses, you should try to standardize the data your app collects as much as possible. Use date and time pickers, stepper controls, input masks, checkboxes, dropdown menu and radio buttons, toggle switches. and so on.</p>
<p>The essence of removing complexity from the user is not only about improving usability, but also about ensuring that the data collected is standardised, structured, and consistent.</p>
<h3 id="heading-design-takeaway-from-teslers-law">Design Takeaway from Tesler's Law</h3>
<p><strong>Push Complexity to the System, Not the User:</strong><br>Every process contains unavoidable complexity. Your job is to handle it behind the scenes so the user experiences the simplest possible interaction.</p>
<p><strong>Automate Tasks Users Shouldn’t Have to Think About:</strong><br>Use tools like autocomplete, fuzzy search, intelligent defaults, and validation APIs to remove manual effort. The complexity still exists — but the system absorbs it instead of the user.</p>
<p><strong>Standardise Inputs to Prevent Messy Data:</strong><br>Users enter the same information in wildly different ways. Use pickers, dropdowns, input masks, radio buttons, and toggles to enforce consistent, structured data collection.</p>
<p><strong>Handle Inherent Technical Complexity Internally:</strong><br>Network issues, API quirks, large dataset sorting, search optimisation, state management, and animation logic are all developer responsibilities. Users should never feel this complexity.</p>
<p><strong>To Sum Up:</strong> Every process contains unavoidable complexity. Your job as a developer is to handle it behind the scenes so the user experiences the simplest possible interaction.</p>
<h2 id="heading-100-peak-end-rule"><strong>10.0 Peak End Rule</strong>:</h2>
<p>In 1993, Daniel Kahneman, Barbara Fredrickson, Charles Schreiber, and Donald Redelmeier invited volunteers into a lab for what sounded like a simple experiment. The task was straightforward: place a hand into a container of painfully cold water (Kahneman et al., 1993)</p>
<p>In the first round, participants kept their hand in 14°C water for 60 seconds. It was uncomfortable, sharp, and unpleasant but after one minute, it was over.</p>
<p>In the second round, they again endured 60 seconds in 14°C water. But this time, they were asked to keep their hand in for an extra 30 seconds. The temperature was raised slightly to 15°C. Still cold. Still unpleasant. Just slightly less intense.</p>
<p>Objectively, the second experience was worse. It lasted 90 seconds instead of 60. More total pain. More suffering.</p>
<p>Later, the researchers asked a simple question:</p>
<p>If you had to repeat one of the trials, which would you choose?” Surprisingly, most participants chose the longer one.</p>
<p>Why would anyone choose more pain?</p>
<p>The researchers realised something profound: people don’t remember experiences by calculating total discomfort. Instead, the mind summarizes the experience using just two key moments — the most intense point (the peak) and the final moment (the end).</p>
<p>In both trials, the peak pain was the same: 14°C. But the longer trial ended slightly better, at 15°C. That small improvement at the end reshaped how the entire episode was remembered. The participants’ “experiencing self” suffered more during the longer trial. But their “remembering self” preferred it because it ended on a less painful note.</p>
<p>From this, the researchers introduced what became known as the Peak–End Rule: we judge experiences largely by their most intense moment and how they finish, not by how long they last.</p>
<p>Since people largely judge an experience by how it ends, developers should focus on designing satisfying confirmation screens and smooth exit interactions. You should concentrate less on making every single moment perfect and instead prioritise optimising the peak and final moments.</p>
<p>A negative ending can overshadow an otherwise good experience, so carefully avoid frustrating final steps such as unexpected fees or confusing confirmations.</p>
<p>Emotional intensity strongly shapes memory, which is why many apps incorporate celebration animations, rewards, or success messages at key moments to leave a lasting positive impression.</p>
<h3 id="heading-design-takeaway-from-peak-end-rule">Design takeaway from Peak End Rule</h3>
<p><strong>People Judge Experiences by the Peak and the Ending — Not the Total Duration:</strong><br>Users don’t remember every moment. They remember the most intense point and how the experience ends. A slightly better ending can completely reshape how the entire interaction is remembered.</p>
<p><strong>Prioritise Strong, Positive Endings in Your UX Flows:</strong><br>A smooth final step, a clear confirmation, or a satisfying success screen leaves a disproportionately strong impression. A bad ending can overshadow an otherwise great experience.</p>
<p><strong>Design for Emotional Peaks at Key Moments:</strong><br>Celebration animations, rewards, checkmarks, and success messages create memorable emotional spikes. These peaks anchor the experience in the user’s memory.</p>
<p><strong>Don’t Try to Perfect Every Moment — Perfect the Right Moments:</strong><br>Optimise the peak and the end of the journey. These two moments define how users recall the entire interaction.</p>
<p><strong>Avoid Negative Surprises at the Finish Line:</strong><br>Unexpected fees, confusing confirmations, or friction at the last step can ruin the memory of the whole process. Protect the ending carefully.</p>
<p><strong>To Sum Up:</strong> We judge experiences largely by their most intense moment and how they finish, not by how long they last.</p>
<h2 id="heading-110-postels-law"><strong>11.0 Postel’s Law</strong>:</h2>
<p>Jon Postel’s famous principle – “Be conservative in what you send, be liberal in what you accept” –&nbsp; is a philosophy of kindness in software design. At its core, the principle argues that systems should be generous with what they accept from users, yet disciplined and predictable in what they output.</p>
<p>When developers follow this approach, users feel supported and understood. When they don’t, users feel punished for being human.</p>
<p>A user’s input is rarely perfect. People type quickly, make mistakes, follow their own habits, or rely on formats familiar to them. A robust system embraces this reality. It accepts messy, human input and quietly transforms it into clean, standardized data.</p>
<p>Real people don't think in strict formats. They write dates the way they learned in school, type phone numbers the way they say them aloud, and enter names and addresses in whatever structure feels natural to them.</p>
<p>A rigid system will reject anything that doesn’t match its narrow expectations, but a robust system, by contrast, adapts to the user.</p>
<p>Consider dates. A brittle interface might demand MM/DD/YYYY and reject everything else. A more humane system accepts a wide range of formats — “1 May 2024,” “2024‑05‑01,” “05/01/24,” or “May 1st, 2024” — and quietly converts them into a standard internal representation. This is where the complex handling described by Tesla's Law comes into play (Shifting complexity to the system, rather than the user).</p>
<p>Phone numbers follow the same pattern. People might enter (555) 123 4567, 555‑123‑4567, 5551234567, or +1 555 123 4567. A fragile system throws errors. A robust one parses all of them using libraries like libphonenumber and moves on.</p>
<p>Addresses are equally varied. “221B Baker St,” “221‑B Baker Street,” and “221 Baker St., Apt B” all refer to the same place. A forgiving system normalizes these instead of rejecting them.</p>
<p>Even names can be surprisingly complex. Hyphens, apostrophes, multiple words, and titles are all part of real human identity. Rejecting “O’Connor,” “Jean‑Luc,” or “Dr. Sarah Lee” is not just technically incorrect — it's disrespectful to the user.</p>
<p>Search bars offer another clear example. A strict search bar demands perfect spelling and exact phrasing. A robust one handles typos (“restuarant”), partial words (“resta”), synonyms (“food places”), and natural language (“where can I eat nearby”). It meets the user where they are instead of forcing them to think like a machine.</p>
<p>Currency should be normalized to a clear format such as GBP 5.00, no matter whether the user typed “£5,” “5 pounds,” or “5 GBP.”</p>
<p>Even file uploads benefit from standardization: whether the user uploads .jpeg, .jpg, .JPG, or .JPEG, the system should store everything as .jpg.</p>
<p>Error messages follow the same principle. Vague feedback like “Invalid password” leaves users confused and frustrated.</p>
<p>A clear, conservative message — “Incorrect password. Please try again.” — respects the user’s time. And instead of hiding password requirements, the system should state them upfront: minimum eight characters, at least one uppercase letter, at least one number.</p>
<p>Predictability reduces friction.</p>
<p>Because users inevitably make mistakes or enter data in unexpected ways, developers should design input fields that are tolerant rather than brittle. This means accepting flexible formats, offering autocorrect or intelligent parsing, and using forgiving validation rules that interpret the user’s intent instead of rejecting their effort.</p>
<p>Clear instructions, tooltips, and visible requirements should appear before submission so users understand what the system expects without trial and error.</p>
<p>When errors do occur, the interface should handle them gently—never crashing, and never forcing the user to start over.</p>
<p>Even simple variations, such as phone numbers typed with spaces, dashes, or parentheses, should be accepted and normalized behind the scenes.</p>
<p>By embracing flexibility on the input side and clarity on the output side, developers create systems that feel humane, resilient, and respectful of the way real people actually behave.</p>
<h3 id="heading-design-takeaway-from-postels-law">Design Takeaway from Postel's Law</h3>
<p><strong>Accept Messy Human Input, Output Clean Structured Data:</strong><br>Users type dates, names, phone numbers, and addresses in unpredictable ways. A humane system accepts this variability and quietly normalises it into a consistent internal format.</p>
<p>Rigid interfaces punish users for being human. Robust interfaces interpret intent — handling typos, partial matches, synonyms, and natural language without complaint.</p>
<p>Also accept variations in spacing, punctuation, casing, and structure. Let users type naturally — the system should handle the complexity, not them.</p>
<p><strong>Be Flexible With Input, Be Strict With Output:</strong><br>This is the heart of Postel’s Law. Let users express information naturally, but ensure your system stores and displays it in a predictable, standardised way.</p>
<p><strong>Use Intelligent Parsing and Autocorrection to Reduce Errors:</strong><br>Libraries like libphonenumber, fuzzy search, and natural‑language parsers allow systems to accept a wide range of formats while still producing clean, reliable data.</p>
<p><strong>Normalise Everything Behind the Scenes:</strong><br>Dates, phone numbers, currency, file extensions, and addresses should all be standardised internally. This prevents messy data and reduces downstream cleanup work.</p>
<p><strong>Provide Clear, Predictable Feedback:</strong><br>Error messages should be specific and helpful. Requirements should be visible upfront. Users should never be surprised, confused, or forced to start over.</p>
<p><strong>Combine Postel’s Law With Tesler’s Law:</strong><br>Shift complexity to the system. Intelligent handling of messy input reduces cognitive load, improves usability, and ensures consistent, high‑quality data.</p>
<p><strong>To Sum Up:</strong> A rigid system will reject anything that doesn’t match its narrow expectations, but a robust system, by contrast, adapts to the user.</p>
<h2 id="heading-120-doherty-threshold"><strong>12.0 Doherty Threshold</strong>:</h2>
<p>The Doherty Threshold is a principle in human–computer interaction which proposes that systems should respond quickly enough to keep users actively engaged (Mod 2024).</p>
<p>When response times stay below a certain limit, users remain focused and productive. But once performance already meets this optimal responsiveness level, making the system even faster or adding extra capability doesn't significantly enhance satisfaction or efficiency.</p>
<p>The idea was introduced by Walter J. Doherty in 1976 in his paper “A Comparison of Programming Systems and Doherty Threshold.” His research showed that maintaining rapid system feedback fast enough to sustain continuous interaction has a stronger impact on productivity than simply increasing system power or features beyond that point.</p>
<p>Doherty proposes that this shouldn't be greater than 400ms Rule: If the system responds within this window, the user feels in total control. If the response takes longer, the user's attention begins to wander, and their "train of thought" is broken.</p>
<p>The challenge, of course, is that not every operation can realistically complete within 400ms. Some tasks require heavy computation, large network calls, or complex rendering. This is where the concept of perceived performance becomes essential.</p>
<p>Even when the system can't finish the work quickly, it can feel fast by responding instantly at the UI level. Developers can achieve this illusion of speed through a combination of thoughtful design patterns and disciplined engineering practices.</p>
<p>On the technical side, performance begins with reducing unnecessary work. Keeping the number of HTML elements low helps the browser render faster. Rendering only the visible portion of long lists prevents the Document Oject Model (DOM) from becoming bloated. Splitting scripts and deferring non‑critical code ensures that essential interactions load first.</p>
<p>Using CSS transforms and opacity changes avoids expensive layout recalculations. Lazy‑loading images, videos, and scripts ensures that the interface becomes interactive long before all assets are downloaded.</p>
<p>These optimizations don’t just improve raw speed — they create the foundation for interfaces that feel responsive.</p>
<h3 id="heading-design-takeaways-from-doherty-threshold">Design Takeaways from Doherty Threshold</h3>
<p><strong>Instant Feedback</strong>: When a user clicks a button, provide a visual change (like a button press animation or a spinner) immediately, even if the background task takes longer.</p>
<p><strong>Skeleton Screens</strong>: Use placeholder blocks that mimic the layout of the page while data loads. This makes the app feel like it is responding instantly.</p>
<p><strong>Progressive Loading</strong>: Load text and basic structures first, then "pop in" high-resolution images later.</p>
<p><strong>Optimistic UI</strong>: When a user hits "Save," don't wait for the server. Update the UI instantly (Doherty) and handle the "messy" data formatting on the backend (Postel).</p>
<p><strong>Live Inline Validation</strong>: Show a green checkmark or a helpful error message as the user types. This keeps them below the 400ms "thought-break" limit.</p>
<p><strong>Debouncing</strong>: In search bars, start showing results after a few keystrokes so the user feels the app is "predicting" their needs.</p>
<p><strong>To Sum Up:</strong> When response times stay below a certain limit, users remain focused and productive. But once performance already meets this optimal responsiveness level, making the system even faster or adding extra capability doesn't significantly enhance satisfaction or efficiency.</p>
<h2 id="heading-130-serial-position-effect-primacy-and-recency"><strong>13.0 Serial Position Effect (Primacy and Recency)</strong>:</h2>
<p>Murdock’s study investigated how the position of a word in a list affects recall, known as the serial position effect. He presented 103 psychology students with lists of 10 to 40 words, one at a time, at either 1 or 2 seconds per word (McLeod, 2025).</p>
<p>Participants were divided into six groups, each experiencing a different combination of list length and presentation rate, and were asked to recall as many words as possible in any order.</p>
<p>The results showed that participants were most likely to remember words at the beginning of the list (primacy effect) and at the end of the list (recency effect), while words in the middle were recalled less often. The recency effect persisted even in longer lists, and the middle section of the recall curve formed a flat asymptote.</p>
<p>Murdock explained this using the multi-store model of memory: early words were rehearsed and transferred to long-term memory, last words remained in short-term memory, and middle words were neither sufficiently rehearsed nor retained, leading to poorer recall.</p>
<p>The experiment demonstrated that memory performance varies systematically with the position of information in a sequence.</p>
<p>This is the reason why the most important information or actions should never be buried in the middle.</p>
<p>As a developer, you should put your most critical navigation links (like "Home" or "Dashboard") at the far left or the top of a list. In a pricing table, put the most popular or recommended plan on the Place "Final Actions" (like "Log Out," "Cart," or "Support") at the end of a menu or the far right of a navigation bar.</p>
<p>In a long onboarding flow, put the most exciting benefit of the app on the very last slide so the user enters the app feeling motivated.</p>
<p>Avoid placing highly important buttons in the middle of a row. If you have a row of 7 buttons, the user is statistically likely to overlook the 4th one.</p>
<h3 id="heading-design-takeaways-serial-position-effect">Design Takeaways <strong>Serial Position Effect</strong></h3>
<p><strong>Place Critical Items at the Beginning or End — Never the Middle:</strong><br>Users reliably remember the first and last items in any sequence (primacy and recency). Anything placed in the middle is statistically more likely to be forgotten or ignored. Also, actions such as “Log Out,” “Cart,” “Support,” or “Checkout” should sit at the far right or bottom — the natural recency position.</p>
<p><strong>Put Essential Navigation Links at the Far Left or Top:</strong><br>Links like “Home,” “Dashboard,” or “Overview” should appear at the start of a menu, where recall and recognition are strongest.</p>
<p><strong>To Sum Up:</strong> The results showed that participants were most likely to remember words at the beginning of the list (primacy effect) and at the end of the list (recency effect), while words in the middle were recalled less often.</p>
<h2 id="heading-140-occams-razor"><strong>14.0 Occam’s Razor</strong>:</h2>
<p>Although first articulated in the 14th century by the Franciscan friar William of Ockham, Occam’s Razor remains one of the most indispensable principles in a developer’s toolkit. In fact, skipping this law while discussing other theories and principles would be like skipping the glue that holds the entire framework together.</p>
<p>At its core, Occam’s Razor states that “among competing explanations, the simplest one is usually the best.”</p>
<p>For example, if two user interfaces achieve the same goal, the one with fewer visual elements is typically superior because it requires less processing power.</p>
<p>The fundamental takeaway for modern developers regarding Occam’s Razor is that complexity is a tax on the user’s cognitive resources.</p>
<p>In an era of information density, the developer's primary role is no longer to provide "more" features – rather, it's to curate the most direct path to a solution.</p>
<p>In practice, Occam’s Razor becomes a reminder to keep things as simple as possible. This “less is more” mindset shapes everything from navigation to forms.</p>
<p>A good rule for navigation is the Rule of Five: aim for three to five main menu items instead of a long, overwhelming list. This keeps choices clear and prevents users from freezing up when they see too many options.</p>
<p>The same idea applies to data entry. When you ask only for the information that truly matters, you respect the user’s time and reduce the chance of “form fatigue,” which is one of the biggest reasons people abandon sign‑ups or checkout flows.</p>
<p>Simplicity isn’t just elegant — it’s practical, humane, and far more effective.</p>
<h3 id="heading-design-takeaway-from-occams-razor">Design Takeaway from Occam's Razor</h3>
<p><strong>Choose the Simplest Effective Solution:</strong><br>When two designs achieve the same goal, the one with fewer elements is almost always better. Simplicity reduces cognitive load and speeds up user decision‑making.</p>
<p><strong>Simplicity Is Not Just Aesthetic — It’s Humane:</strong><br>Clear, minimal interfaces respect the user’s time, reduce friction, and make the product feel effortless. Simplicity is both a design strategy and an act of empathy.</p>
<p><strong>To Sum Up:</strong> Simplicity isn’t just elegant — it’s practical, humane, and far more effective.</p>
<h2 id="heading-150-parkinsons-law">15.0 Parkinson's Law</h2>
<p>Occam’s Razor teaches us to prefer the simplest solution that works. But why do we so often end up with complex systems in the first place? That tendency is explained by another principle: Parkinson’s Law.</p>
<p>Parkinson’s Law states that "work expands to fill the time available for its completion". In design, this means projects often become overly complex or take longer than necessary if given too much time, resulting in inefficient, over-designed, or cluttered interfaces.</p>
<p>In design, this manifests as Feature Creep. If you give yourself three months to build an app, you will spend three months adding "nice-to-have" animations, extra settings toggles, and niche edge cases that nobody asked for and in reality, what you have added isn’t that important.</p>
<p>You just succeeded in adding layers of complexity that might ends up violating some of the laws we spoke about. Occam’s Razor reminds us that the simplest solution is often the most effective.</p>
<p>By being aware of Parkinson’s Law and the tendency for work to expand, developers can manage their time intentionally and focus only on what truly matters.</p>
<h3 id="heading-design-takeaway-for-parkinsons-law">Design Takeaway for Parkinson's law</h3>
<p><strong>Set Clear Constraints to Keep Designs Focused:</strong><br>Intentional time limits and scope boundaries prevent over‑designing. Constraints force clarity, prioritisation, and simplicity.</p>
<p><strong>Build Only What Truly Matters for the User:</strong><br>Parkinson’s Law reminds you to resist the urge to fill time with unnecessary features. Focus on the core experience, not the edge cases nobody asked for.</p>
<p><strong>Use Occam’s Razor to Counterbalance Parkinson’s Law:</strong><br>As work expands, complexity grows. Occam’s Razor pulls you back to the simplest effective solution. Together, the two principles prevent bloated, over‑engineered products.</p>
<p><strong>To Sum Up:</strong> Work expands to fill the time available for its completion</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Human-centered design is deeply influenced by a set of psychological principles that explain how users perceive, process, and interact with digital systems.</p>
<p>Among these, Fitts’s Law establishes that the time required to acquire a target depends on its size and distance. In practice, this means that larger and closer elements are easier and faster to interact with.</p>
<p>To apply this in practice, developers should make primary call-to-action elements prominent, large, and easily reachable –&nbsp;especially in mobile interfaces where thumb accessibility is critical.</p>
<p>Closely related to decision-making is Hick’s Law, which states that the more choices a user is presented with, the longer it takes to make a decision. Excessive options can overwhelm users and lead to decision fatigue.</p>
<p>To address this, developers should simplify interfaces, minimise unnecessary options, and guide users through processes step-by-step rather than presenting everything at once.</p>
<p>Another important cognitive principle discussed is Miller’s Law, which suggests that the average person can hold approximately seven (plus or minus two) items in working memory at a time. This limitation highlights the need to present information in manageable chunks.</p>
<p>By breaking content into smaller groups and avoiding information overload, developers can improve comprehension and usability.</p>
<p>User expectations are strongly shaped by Jakob’s Law, which says that people spend most of their time on other websites and therefore expect similar patterns across digital products.</p>
<p>Instead of reinventing basic interactions, developers should follow familiar conventions such as placing the logo in the top‑left, the shopping cart in the top‑right, and keeping scrolling behaviour predictable.</p>
<p>But innovation is still possible where it truly adds value. As we discussed with the Aesthetic‑Usability Effect, users are far more tolerant of new or unusual design patterns when the interface is visually appealing and thoughtfully crafted.</p>
<p>The Gestalt Principles provided additional insight into how users visually organise information. The principle of proximity suggests that objects placed close together are perceived as related, so grouping related elements improves clarity. Similarity indicates that elements with consistent colours, shapes, or styles are seen as belonging together, reinforcing visual hierarchy and function. Closure explains that users can perceive incomplete shapes as complete, allowing for minimalistic designs where the brain fills in missing details. Continuity highlights that users naturally follow smooth visual paths, meaning layouts should guide the eye logically through alignment and structure.</p>
<p>We also looked at The Von Restorff Effect which emphasizes that elements which stand out are more likely to be remembered. By using contrast in colour, size, or design, important features such as buttons or alerts can capture user attention.</p>
<p>Managing complexity was addressed by Tesler’s Law, which asserts that every system has inherent complexity that cannot be eliminated but only managed.</p>
<p>Developers must therefore shift complexity away from the user by simplifying interfaces while handling intricate processes behind the scenes.</p>
<p>The Zeigarnik Effect reveals that people remember unfinished tasks better than completed ones, creating a sense of mental tension. This can be leveraged by incorporating progress indicators, checklists, and reminders that encourage users to complete tasks.</p>
<p>Similarly, the Peak-End Rule suggests that users judge an experience based on its most intense moment and its conclusion. Developers should create memorable highlights and ensure a smooth, satisfying ending to user journeys.</p>
<p>We also discussed the Goal-Gradient Effect, which explains that users become more motivated as they approach the completion of a task. By showing progress –such as indicating that a process is “80% complete” –&nbsp;and breaking tasks into stages, developers can encourage users to finish what they have started.</p>
<p>In terms of system interaction, Postel’s Law advises developers to be flexible in accepting user input while maintaining strict standards for output. This means allowing different input formats while ensuring consistent and reliable system responses.</p>
<p>Performance is equally important, as highlighted by the Doherty Threshold, which shows that productivity increases when system response times stay under 400 milliseconds. Fast systems keep users engaged and create a sense of ease.</p>
<p>This means that developers should focus on building interfaces that feel instant, even when real processing takes longer, by combining smart engineering practices with thoughtful design patterns that maintain the illusion of speed.</p>
<p>Memory and attention are further explained by the Serial Position Effect, where users tend to remember the first and last items in a sequence more than those in the middle. Developers should position key information or actions at the beginning or end of lists.</p>
<p>Simplicity is reinforced by Occam’s Razor, which argues that the simplest solution is often the most effective. Eliminating unnecessary features reduces friction and enhances usability, and we further discussed about Parkinson’s Law, which suggests that tasks expand to fill the time available, indicating the importance of setting constraints such as deadlines or timers to encourage timely action.</p>
<p>These principles collectively highlight the importance of simplicity, clarity, performance, and user psychology in design. By applying them thoughtfully, developers can create intuitive, efficient, and engaging user experiences that align with both human behaviour and user expectations.</p>
<h2 id="heading-references">References</h2>
<p>Budiu, R. (2022). <em>Fitts’s Law and Its Applications in UX</em>. [online] Nielsen Norman Group. Available at: <a href="https://www.nngroup.com/articles/fitts-law/">https://www.nngroup.com/articles/fitts-law/</a>.</p>
<p>Bustamante, N. (2023). <em>Gestalt Psychology? Definition, Principles, &amp; Examples - Simply Psychology</em>. [online] <a href="http://www.simplypsychology.org">www.simplypsychology.org</a>. Available at: <a href="https://www.simplypsychology.org/what-is-gestalt-psychology.html">https://www.simplypsychology.org/what-is-gestalt-psychology.html</a>.</p>
<p>Cherry, K. (2024). <em>The Zeigarnik Effect Is Why You Keep Thinking of Unfinished Work</em>. [online] Verywell Mind. Available at: <a href="https://www.verywellmind.com/zeigarnik-effect-memory-overview-4175150">https://www.verywellmind.com/zeigarnik-effect-memory-overview-4175150</a>.</p>
<p>DO, A.M., RUPERT, A.V. and WOLFORD, G. (2008). Evaluations of pleasurable experiences: The peak-end rule. <em>Psychonomic Bulletin &amp; Review</em>, 15(1), pp.96–98. doi:<a href="https://doi.org/10.3758/pbr.15.1.96">https://doi.org/10.3758/pbr.15.1.96</a>.</p>
<p>GUPTA, S., GUPTA, S., MAHENDRA, A. and GUPTA, S. (2006). Inverse Halo Nevus. <em>Dermatologic Surgery</em>, 32(6), pp.871–872. doi:<a href="https://doi.org/10.1097/00042728-200606000-00025">https://doi.org/10.1097/00042728-200606000-00025</a>.</p>
<p>‌Hall, D. (2023). <em>Pilot Error, Chapanis and The Shape of Things to Come</em>. [online] UX Magazine. Available at: <a href="https://uxmag.com/articles/pilot-error-chapanis-and-the-shape-of-things-to-come">https://uxmag.com/articles/pilot-error-chapanis-and-the-shape-of-things-to-come</a>.</p>
<p>Hunt, R.R. (1995). The subtlety of distinctiveness: What von Restorff really did. <em>Psychonomic Bulletin &amp; Review</em>, 2(1), pp.105–112. doi:<a href="https://doi.org/10.3758/bf03214414">https://doi.org/10.3758/bf03214414</a>.</p>
<p>Kahneman, D., Fredrickson, B.L., Schreiber, C.A. and Redelmeier, D.A. (1993). When More Pain Is Preferred to Less: Adding a Better End. <em>Psychological Science</em>, 4(6), pp.401–405. doi:<a href="https://doi.org/10.1111/j.1467-9280.1993.tb00589.x">https://doi.org/10.1111/j.1467-9280.1993.tb00589.x</a>.</p>
<p>Mod, D. (2024). <em>Doherty Threshold: UX Law of Swift Interactions</em>. [online] Articles on everything UX: Research, Testing &amp; Design. Available at: <a href="https://blog.uxtweak.com/doherty-threshold/">https://blog.uxtweak.com/doherty-threshold/</a>.</p>
<p>Miller, G.A. (1956). The magical number seven, plus or minus two: Some limits on our capacity for processing information. <em>Psychological Review</em>, [online] 101(2), pp.343–352. doi:<a href="https://doi.org/10.1037/0033-295x.101.2.343">https://doi.org/10.1037/0033-295x.101.2.343</a>.</p>
<p>Proctor, R.W. and Schneider, D.W. (2018). Hick’s law for choice reaction time: A review. <em>Quarterly Journal of Experimental Psychology</em>, [online] 71(6), pp.1281–1299. doi:<a href="https://doi.org/10.1080/17470218.2017.1322622">https://doi.org/10.1080/17470218.2017.1322622</a>.</p>
<p>Yablonski, J. (2022). <em>Hick’s Law</em>. [online] Laws of UX. Available at: <a href="https://lawsofux.com/hicks-law/">https://lawsofux.com/hicks-law/</a>.</p>
<p>Yablonski, J. (2022). <em>Goal-Gradient Effect</em>. [online] Laws of UX. Available at: <a href="https://lawsofux.com/goal-gradient-effect/">https://lawsofux.com/goal-gradient-effect/</a>.</p>
<p>‌</p>
<p>‌</p>
<p>‌</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Responsive UIs in Flutter ]]>
                </title>
                <description>
                    <![CDATA[ Building responsive UIs in Flutter can be challenging, especially when you want your app to look great on phones, tablets, and desktops without maintaining multiple layouts. Fortunately, Flutter provides powerful tools like MediaQuery, LayoutBuilder,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-responsive-uis-in-flutter/</link>
                <guid isPermaLink="false">690108bed60a2bc774c2f435</guid>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Atuoha Anthony ]]>
                </dc:creator>
                <pubDate>Tue, 28 Oct 2025 18:17:34 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761675310940/332589a7-55e0-4cb2-935e-aa1011709e2e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building responsive UIs in Flutter can be challenging, especially when you want your app to look great on phones, tablets, and desktops without maintaining multiple layouts. Fortunately, Flutter provides powerful tools like <code>MediaQuery</code>, <code>LayoutBuilder</code>, and the <code>flutter_screenutil</code> package to make this process seamless.</p>
<p>In this article, we’ll walk through a complete sample responsive screen, explaining each part of the code step by step. You’ll learn not only how to make your layout adapt to different screen sizes and orientations but also how to use scaling utilities to keep your text and spacing consistent across all devices.</p>
<p>By the end, you’ll understand how to structure a Flutter app that automatically adjusts its layout and typography based on the available screen real estate, a must-know skill for any developer targeting multiple platforms.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-responsive-vs-adaptive-design">Understanding Responsive vs Adaptive Design</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-core-flutter-layout-widgets-for-responsive-ui">Core Flutter Layout Widgets for Responsive UI</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-containersizedbox">Container/SizedBox</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-overly-fixed-sizing-not-responsive">Overly Fixed Sizing (Not Responsive)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-responsive-flexible-sizing">Responsive / Flexible Sizing</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sizedbox-for-spacing-or-constraints">SizedBox for Spacing or Constraints</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-row-column">Row, Column</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-expanded-and-flexible">Expanded and Flexible</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-layoutbuilder">LayoutBuilder</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-mediaquery-and-screen-information">MediaQuery and Screen Information</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-breakpoints-orientation-and-large-screen-adaptation">Breakpoints, Orientation and Large-Screen Adaptation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-responsive-typography-images-and-assets">Responsive Typography, Images and Assets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-flexible-layouts-expanded-flexible-fractionallysizedbox">Flexible Layouts: Expanded, Flexible, FractionallySizedBox</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-advanced-tools-and-packages">Advanced Tools and Packages</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-handling-safe-areas-notches-and-insets">Handling Safe Areas, Notches and Insets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-adaptive-ui-for-tabletsdesktop-and-multi-window">Adaptive UI for Tablets/Desktop and Multi-Window</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-and-performance-considerations">Best Practices and Performance Considerations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-and-debugging-responsive-layouts">Testing and Debugging Responsive Layouts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-reusable-responsive-widgetscustom-widgets">Building Reusable Responsive Widgets/Custom Widgets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-example-of-a-complete-sample-responsive-screen">Example of A Complete Sample Responsive Screen</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-project-setup-and-imports">Project Setup and Imports</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-app-entry-point-the-myapp-class">App Entry Point: The MyApp Class</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-responsive-home-screen-myhomepage">The Responsive Home Screen (MyHomePage)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-core-content">Building the Core Content</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-full-walkthrough-code-explained-in-depth">Full Walkthrough: Code Explained in Depth</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-imports-and-app-entry-point">Imports and App Entry Point</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-app-root-the-myapp-widget">App Root: The MyApp Widget</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-home-screen-layout-myhomepage">The Home Screen Layout MyHomePage</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-scaffold-and-appbar">The Scaffold and AppBar</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-safearea-layoutbuilder">SafeArea + LayoutBuilder</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-handling-large-and-small-screens">Handling Large and Small Screens</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-core-content-1">Building the Core Content</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-this-works">Why This Works</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-key-takeaways">Key Takeaways</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-references">References</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving in, ensure you have:</p>
<ul>
<li><p>A working Flutter environment (SDK, IDE, emulator or device).</p>
</li>
<li><p>Basic proficiency in Flutter: Knowledge of widgets, stateless/stateful, Row/Column, Scaffold, and so on.</p>
</li>
<li><p>Familiarity with Dart basics and how layout works in Flutter (constraints, sizing).</p>
</li>
<li><p>(Optional but helpful) A design/mockup (for example from Figma) with defined design size or target screen.</p>
</li>
<li><p>Understanding that creating truly adaptive/responsive UIs means accommodating <strong>different screen sizes</strong>, <strong>orientations</strong>, <strong>aspect-ratios</strong>, and <strong>platforms</strong> (mobile/tablet/web/desktop).</p>
</li>
</ul>
<h2 id="heading-understanding-responsive-vs-adaptive-design">Understanding Responsive vs Adaptive Design</h2>
<p>It’s helpful to clarify terminology:</p>
<ul>
<li><p><strong>Responsive design</strong> is about <em>fitting</em> the UI into the available space: The layout scales, reflows, rearranges as the screen size or orientation changes.</p>
</li>
<li><p><strong>Adaptive design</strong> is about selecting different UI patterns depending on the device/screen. For example, using a side-panel on desktop, bottom navigation on mobile. The UI adapts to the context of use.</p>
</li>
<li><p>In practice with Flutter, you often do <em>both</em>: Responsive (scaling/reflow) and adaptive (choosing variant layouts).</p>
</li>
<li><p>According to the official documentation:</p>
<blockquote>
<p>“Responsive design is about fitting the UI into the space. Adaptive design is about the UI being usable in the space.” (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive">Flutter Docs</a>)</p>
</blockquote>
</li>
<li><p>Also, some best practices to follow: don’t assume device type (phone/tablet) based on screen size, don’t lock orientation, and don’t rely solely on <code>MediaQuery.orientation</code>. (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive/best-practices">Flutter Docs</a>)</p>
</li>
</ul>
<h2 id="heading-core-flutter-layout-widgets-for-responsive-ui">Core Flutter Layout Widgets for Responsive UI</h2>
<p>Flutter provides many fundamental widgets for layout – when used well, they form the backbone of responsive UIs.</p>
<ol>
<li><h3 id="heading-containersizedbox">Container/SizedBox</h3>
</li>
</ol>
<p><code>Container</code>, <code>SizedBox</code> let you size widgets explicitly or via constraints.</p>
<p>Use cautiously: Overly fixed sizes can hamper responsiveness (for example, a Container(width: 300) may overflow on small screens).</p>
<p>Better to use relative sizing or allow flexibility.</p>
<p>Here are clear, practical Flutter code examples that illustrate <strong>how to use</strong> <code>Container</code> and <code>SizedBox</code>, including both <strong>bad (fixed)</strong> and <strong>good (responsive/flexible)</strong> sizing approaches:</p>
<h3 id="heading-overly-fixed-sizing-not-responsive">Overly Fixed Sizing (Not Responsive)</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FixedContainerExample</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      body: Center(
        <span class="hljs-comment">// This might overflow on small screens!</span>
        child: Container(
          width: <span class="hljs-number">300</span>,
          height: <span class="hljs-number">200</span>,
          color: Colors.blue,
          child: <span class="hljs-keyword">const</span> Center(
            child: Text(
              <span class="hljs-string">'Fixed Size Container'</span>,
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }
}
</code></pre>
<p><strong>Problem:</strong><br>If the screen width is less than 300px (like on small mobile devices), this widget may overflow or get cut off.</p>
<h3 id="heading-responsive-flexible-sizing">Responsive / Flexible Sizing</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveContainerExample</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> screenWidth = MediaQuery.of(context).size.width;

    <span class="hljs-keyword">return</span> Scaffold(
      body: Center(
        <span class="hljs-comment">// Use relative width and height</span>
        child: Container(
          width: screenWidth * <span class="hljs-number">0.8</span>, <span class="hljs-comment">// 80% of screen width</span>
          height: <span class="hljs-number">200</span>,
          decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.circular(<span class="hljs-number">12</span>),
          ),
          child: <span class="hljs-keyword">const</span> Center(
            child: Text(
              <span class="hljs-string">'Responsive Container (80% width)'</span>,
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }
}
</code></pre>
<p><strong>Why better:</strong><br>It adjusts automatically to different screen sizes.</p>
<h3 id="heading-sizedbox-for-spacing-or-constraints">SizedBox for Spacing or Constraints</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SizedBoxExample</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            <span class="hljs-keyword">const</span> Text(<span class="hljs-string">'Above Spacer'</span>),
            <span class="hljs-keyword">const</span> SizedBox(height: <span class="hljs-number">16</span>), <span class="hljs-comment">// Adds spacing</span>
            Container(
              width: <span class="hljs-number">200</span>,
              height: <span class="hljs-number">100</span>,
              color: Colors.green,
              child: <span class="hljs-keyword">const</span> Center(child: Text(<span class="hljs-string">'Sized Container'</span>)),
            ),
          ],
        ),
      ),
    );
  }
}
</code></pre>
<p><code>SizedBox</code> is lightweight and great for adding <strong>fixed spacing</strong> or defining <strong>simple dimensions</strong> without needing a full <code>Container</code>.</p>
<ol start="2">
<li><h3 id="heading-row-column">Row, Column</h3>
</li>
</ol>
<p><code>Row</code> and <code>Column</code> arrange children horizontally or vertically.</p>
<p><strong>Note</strong>: <code>Row</code> gives infinite horizontal space (subject to parent constraints), so children must handle sizing or else overflow.</p>
<p>When you use a <strong>Row</strong> or <strong>Column</strong>, Flutter tries to give them as much space as possible <strong>along their main axis</strong> (horizontal for Row, vertical for Column).<br>If the children inside don’t know how much space to take, <strong>they can overflow</strong> or not display as intended.</p>
<p>That’s why we use <code>Expanded</code>, <code>Flexible</code>, or <code>SizedBox</code> to tell Flutter <strong>how each child should use the available space</strong>.</p>
<p>Example:</p>
<pre><code class="lang-dart">Row(
  children: [
    Expanded(
      child: Container(
        <span class="hljs-comment">// Your widget content here</span>
      ),
    ),
    <span class="hljs-comment">// Other widgets...</span>
  ],
)
</code></pre>
<p>Here <code>Expanded</code> says: “take up remaining space proportionally”.</p>
<h3 id="heading-expanded-and-flexible">Expanded and Flexible</h3>
<p><code>Expanded</code> forces its child to fill remaining space in a <code>Row</code> or <code>Column</code>.</p>
<p><code>Flexible</code> gives its child flexibility: it may shrink or grow but not forcibly fill.</p>
<p>Example:</p>
<pre><code class="lang-dart">Row(
  children: [
    Flexible(
      child: Container(
        <span class="hljs-comment">// Widget content</span>
      ),
    ),
    <span class="hljs-comment">// Other widgets...</span>
  ],
)
</code></pre>
<p>Using <code>Flexible</code>/<code>Expanded</code> helps distribute space dynamically and naturally adapt to varying screen sizes.</p>
<ol start="3">
<li><h3 id="heading-layoutbuilder">LayoutBuilder</h3>
</li>
</ol>
<p><code>LayoutBuilder</code> gives you the parent widget’s constraints (<code>maxWidth</code>, <code>maxHeight</code>) and allows you to re-build UI accordingly.</p>
<pre><code class="lang-dart">LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    <span class="hljs-keyword">if</span> (constraints.maxWidth &gt; <span class="hljs-number">600</span>) {
      <span class="hljs-comment">// Large screen layout</span>
      <span class="hljs-keyword">return</span> LargeScreenWidget();
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// Small screen layout</span>
      <span class="hljs-keyword">return</span> SmallScreenWidget();
    }
  },
)
</code></pre>
<p>This is often more reliable than just checking <code>MediaQuery.orientation</code> or <code>MediaQuery.size</code>, especially in multi-window/foldable devices. (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive/best-practices?utm_source=chatgpt.com">Flutter Docs</a>)</p>
<ol start="4">
<li><h4 id="heading-fractionallysizedbox-and-aspectratio">FractionallySizedBox and AspectRatio</h4>
</li>
</ol>
<p><code>FractionallySizedBox</code>: Sizes its child as a fraction of the parent’s size (for example, <code>widthFactor: 0.5</code>).</p>
<p><code>AspectRatio</code>: Maintains a fixed aspect ratio (width/height), useful for images or containers.</p>
<pre><code class="lang-dart">AspectRatio(
  aspectRatio: <span class="hljs-number">16</span> / <span class="hljs-number">9</span>,
  child: YourWidget(),
)
</code></pre>
<p>These help maintain proportionally consistent layouts across screen sizes.</p>
<h2 id="heading-mediaquery-and-screen-information">MediaQuery and Screen Information</h2>
<p>Understanding screen size, orientation, padding, device pixel ratio and so on, is essential.</p>
<h4 id="heading-using-mediaquery">Using MediaQuery</h4>
<pre><code class="lang-dart"><span class="hljs-built_in">double</span> screenWidth  = MediaQuery.of(context).size.width;
<span class="hljs-built_in">double</span> screenHeight = MediaQuery.of(context).size.height;
Orientation orientation = MediaQuery.of(context).orientation;
<span class="hljs-built_in">double</span> devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
EdgeInsets padding = MediaQuery.of(context).padding;
</code></pre>
<p><code>size</code> gives the logical pixel width/height, <code>orientation</code> informs if the device is in portrait or landscape, <code>devicePixelRatio</code> shows how many physical pixels per logical pixel, helpful for image scaling, and <code>padding</code> gives system UI insets (notches, status bar, navigation bar).</p>
<p>Use these values to tailor your UI: for example, adjust font sizes, container widths, or layout decisions.</p>
<h4 id="heading-example-responsive-typography">Example: Responsive Typography</h4>
<pre><code class="lang-dart">Text(
  <span class="hljs-string">'Your text here'</span>,
  style: TextStyle(
    fontSize: screenWidth * <span class="hljs-number">0.04</span>, <span class="hljs-comment">// 4% of screen width</span>
  ),
)
</code></pre>
<p>Approach: Compute font size relative to screen width or height. But be cautious, text readability and accessibility (for example, system font size changes) should be considered, see best practices below.</p>
<h3 id="heading-breakpoints-orientation-and-large-screen-adaptation">Breakpoints, Orientation and Large-Screen Adaptation</h3>
<p>To create UIs that look great on tablets/desktops as well as phones:</p>
<h4 id="heading-orientation">Orientation</h4>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (MediaQuery.of(context).orientation == Orientation.portrait) {
  <span class="hljs-comment">// Portrait layout</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// Landscape layout</span>
}
</code></pre>
<p>Works for basic cases, but beware: orientation alone doesn’t capture window size (especially in desktop/multi-window environments), prefer checking constraints or size. (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive/best-practices?utm_source=chatgpt.com">Flutter Docs</a>)</p>
<h4 id="heading-breakpoints-and-adaptive-layouts">Breakpoints and Adaptive Layouts</h4>
<p>Define custom breakpoints based on width (or other metrics) to trigger different layouts.</p>
<p>Example:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (screenWidth &gt; <span class="hljs-number">600</span>) {
  <span class="hljs-comment">// Tablet/large-screen UI</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// Phone UI</span>
}
</code></pre>
<p>Some sources propose standard breakpoints, for example, compact (&lt;600), medium (600-840), large (&gt;840). With <code>LayoutBuilder</code> you can detect parent constraint width instead of global screen width, which is more robust.</p>
<h4 id="heading-large-screens-and-safe-use-of-space">Large Screens and Safe Use of Space</h4>
<p>On very wide screens, filling full width may hurt readability. The official Flutter docs recommend limiting content width (for example, using <code>ConstrainedBox</code> + <code>Center</code>) for large screens so that lines of text aren't excessively long. (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive/best-practices?utm_source=chatgpt.com">Flutter Docs</a>)</p>
<p>Example:</p>
<pre><code class="lang-dart">Center(
  child: ConstrainedBox(
    constraints: BoxConstraints(maxWidth: <span class="hljs-number">800</span>),
    child: YourContent(),
  ),
)
</code></pre>
<h3 id="heading-responsive-typography-images-and-assets">Responsive Typography, Images and Assets</h3>
<h4 id="heading-typography">Typography</h4>
<p>Use scalable units whenever possible (see packages later). Wrap text in <code>Flexible</code>/<code>Expanded</code> if inside <code>Row</code>/<code>Column</code> to avoid overflow, and consider system font scale factor: You can use <code>MediaQuery.of(context).textScaleFactor</code> to adapt fonts for accessibility.</p>
<h4 id="heading-images-and-boxfit">Images and BoxFit</h4>
<pre><code class="lang-dart">Image.asset(
  <span class="hljs-string">'assets/your_image.png'</span>,
  fit: BoxFit.cover,  <span class="hljs-comment">// or BoxFit.contain, BoxFit.fitWidth etc.</span>
  width: someWidth,   <span class="hljs-comment">// responsive width</span>
  height: someHeight, <span class="hljs-comment">// responsive height</span>
)
</code></pre>
<p><code>BoxFit.cover</code> allows image to fill container while maintaining aspect ratio.</p>
<p>Use <code>AspectRatio</code> or <code>FractionallySizedBox</code> to keep images proportional.</p>
<h4 id="heading-asset-density-and-pixel-ratio">Asset Density and Pixel Ratio</h4>
<p>For high resolution devices (high <code>devicePixelRatio</code>), provide higher resolution assets (2x/3x) so they appear crisp.</p>
<p>Flutter handles asset variants (<code>asset@2x.png</code> and so on) automatically, but in very large screen layouts you may want extra details.</p>
<h3 id="heading-flexible-layouts-expanded-flexible-fractionallysizedbox">Flexible Layouts: Expanded, Flexible, FractionallySizedBox</h3>
<p>We discussed these partially above, but here are deeper guidelines.</p>
<h4 id="heading-expanded-and-flexible-1">Expanded and Flexible</h4>
<p>Use inside <code>Row</code> or <code>Column</code> to distribute space.</p>
<p>Example:</p>
<pre><code class="lang-dart">Row(
  children: [
    Expanded(flex: <span class="hljs-number">2</span>, child: Container(color: Colors.red)),
    SizedBox(width: <span class="hljs-number">8</span>),
    Expanded(flex: <span class="hljs-number">1</span>, child: Container(color: Colors.blue)),
  ],
)
</code></pre>
<p>The red container takes twice the width of the blue. Using <code>Flexible</code> allows its child to expand or shrink, but doesn’t force full space.</p>
<h4 id="heading-fractionallysizedbox">FractionallySizedBox</h4>
<p>Example:</p>
<pre><code class="lang-dart">FractionallySizedBox(
  widthFactor: <span class="hljs-number">0.8</span>,  <span class="hljs-comment">// 80% of parent width</span>
  child: SomeWidget(),
)
</code></pre>
<p>Useful when you want a widget to occupy a fraction of available space without using exact pixel values.</p>
<h4 id="heading-aspectratio">AspectRatio</h4>
<pre><code class="lang-dart">AspectRatio(
  aspectRatio: <span class="hljs-number">16</span>/<span class="hljs-number">9</span>,
  child: Container(color: Colors.green),
)
</code></pre>
<p>Ensures the container maintains 16:9 ratio regardless of parent size.</p>
<h3 id="heading-advanced-tools-and-packages">Advanced Tools and Packages</h3>
<p>Using packages can simplify many repetitive tasks. Here are some highly used ones.</p>
<h4 id="heading-flutterscreenutil">flutter_screenutil</h4>
<p>Helps scale widths, heights, font sizes based on a design size you specify.</p>
<p>Example initialization:</p>
<pre><code class="lang-dart">ScreenUtilInit(
  designSize: Size(<span class="hljs-number">360</span>, <span class="hljs-number">690</span>), <span class="hljs-comment">// your base design size</span>
  builder: () =&gt; MaterialApp(
    home: MyHomePage(),
  ),
);
</code></pre>
<p>Usage:</p>
<pre><code class="lang-dart">width: <span class="hljs-number">200.</span>w,         <span class="hljs-comment">// scaled width</span>
height: <span class="hljs-number">150.</span>h,        <span class="hljs-comment">// scaled height</span>
fontSize: <span class="hljs-number">16.</span>sp,      <span class="hljs-comment">// scaled font size</span>
radius: <span class="hljs-number">12.</span>r,         <span class="hljs-comment">// scaled radius</span>
</code></pre>
<p>Advantages: Easy scaling of many sizes. But you must use <code>.w</code>, <code>.h</code>, <code>.sp</code>, <code>.r</code> consistently.</p>
<h4 id="heading-responsivebuilder">responsive_builder</h4>
<p>Helps produce layouts for different device screen types (mobile/tablet/desktop).</p>
<p>Example:</p>
<pre><code class="lang-dart">ResponsiveBuilder(
  builder: (context, sizingInformation) {
    <span class="hljs-keyword">if</span> (sizingInformation.deviceScreenType == DeviceScreenType.mobile) {
      <span class="hljs-keyword">return</span> MobileLayout();
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (sizingInformation.deviceScreenType == DeviceScreenType.tablet) {
      <span class="hljs-keyword">return</span> TabletLayout();
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> DesktopLayout();
    }
  },
);
</code></pre>
<p>Useful for switching entire widget trees based on device type. (<a target="_blank" href="https://medium.com/%40ravipatel84184/mastering-responsive-ui-in-flutter-a-comprehensive-guide-49c4ba9902af?utm_source=chatgpt.com">Medium</a>)</p>
<h4 id="heading-others">Others</h4>
<ol>
<li><p><code>responsive_framework</code>, <code>adaptive_breakpoints</code>, and so on.</p>
</li>
<li><p>When choosing a package, check maintenance, popularity, compatibility with your Flutter version.</p>
</li>
</ol>
<h3 id="heading-handling-safe-areas-notches-and-insets">Handling Safe Areas, Notches and Insets</h3>
<p>Modern devices have notches, status bars, navigation bars, foldables and so on. Use widgets and APIs to handle these.</p>
<ol>
<li><p>Wrap main content in <code>SafeArea</code> to avoid system UI intrusions.</p>
</li>
<li><p>Use <code>MediaQuery.of(context).padding</code> to detect safe padding (top, bottom, left, right).</p>
</li>
</ol>
<p>Example:</p>
<pre><code class="lang-dart">Padding(
  padding: MediaQuery.of(context).padding,
  child: YourContent(),
)
</code></pre>
<p>On Android you can also set UI mode:</p>
<pre><code class="lang-dart">SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
</code></pre>
<p>and update styles so status/navigation bar become transparent, helps full-screen UIs.</p>
<h3 id="heading-adaptive-ui-for-tabletsdesktop-and-multi-window">Adaptive UI for Tablets/Desktop and Multi-Window</h3>
<p>As your app runs on larger screens or in multi-window environments (foldables, desktops, web), consider:</p>
<ol>
<li><p>Switching from bottom navigation (mobile) to a navigation rail or side‐panel (tablet/desktop).</p>
</li>
<li><p>Using <code>ConstrainedBox</code> to limit content width on wide screens for readability.</p>
</li>
<li><p>Layout changes: Instead of single column scroll, you may display side-by-side panels or grid layouts.</p>
</li>
<li><p>Use <code>LayoutBuilder</code> or packages to detect width/constraints and choose the appropriate layout.</p>
</li>
<li><p>Avoid device type checking (for example, “if tablet”), instead base on window size.</p>
<p> Example:</p>
<pre><code class="lang-dart"> LayoutBuilder(
   builder: (context, constraints) {
     <span class="hljs-keyword">if</span> (constraints.maxWidth &gt; <span class="hljs-number">1024</span>) {
       <span class="hljs-keyword">return</span> DesktopScaffold();
     } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (constraints.maxWidth &gt; <span class="hljs-number">600</span>) {
       <span class="hljs-keyword">return</span> TabletScaffold();
     } <span class="hljs-keyword">else</span> {
       <span class="hljs-keyword">return</span> MobileScaffold();
     }
   },
 );
</code></pre>
</li>
</ol>
<h2 id="heading-best-practices-and-performance-considerations">Best Practices and Performance Considerations</h2>
<p>Summarizing key best practices:</p>
<ol>
<li><p><strong>Break widgets into smaller reusable widgets</strong> improves maintainability and reuse.</p>
</li>
<li><p><strong>Start building from the inside out</strong>. Start with smallest components and move outward, rather than imposing outer container constraints first.</p>
</li>
<li><p><strong>Ensure defined constraints</strong> to avoid infinite bounds and overflow by using <code>Expanded</code>, <code>Flexible</code>, and so on.</p>
</li>
<li><p><strong>Avoid fixed sizes where unnecessary</strong>. Relative sizing or flex layouts adapt better.</p>
</li>
<li><p><strong>Avoid relying solely on screen size or orientation</strong>, use constraints instead of device type checks.</p>
</li>
<li><p><strong>Performance matters</strong>, avoid over-nesting heavy layouts, avoid rebuilding large subtrees when not needed. Use <code>const</code> widgets and keep build method lean.</p>
</li>
<li><p><strong>Accessibility</strong> account for large font scaling (<code>MediaQuery.textScaleFactor</code>), screen readers, keyboard/mouse input on larger screens.</p>
</li>
<li><p><strong>Test on multiple screen sizes/orientations</strong> actual devices/emulators/display sizes.</p>
</li>
<li><p><strong>Font/text overflow</strong> wrap text in <code>Flexible</code>, set <code>overflow</code>, <code>softWrap</code>, and test for dynamic content.</p>
</li>
</ol>
<h2 id="heading-testing-and-debugging-responsive-layouts">Testing and Debugging Responsive Layouts</h2>
<ol>
<li><p>Use device emulators/simulators with different screen sizes (phones, tablets, desktops).</p>
</li>
<li><p>For web/desktop, resize browser window to see how layout adapts.</p>
</li>
<li><p>Use <code>device_preview</code> package or built-in Flutter tools to simulate various devices.</p>
</li>
<li><p>Use Flutter DevTools’ <strong>Widget Inspector</strong> and <strong>Layout Explorer</strong> to understand how widgets are sized and laid out.</p>
</li>
<li><p>Test orientation changes, multi-window, split view (for example, Android foldables).</p>
</li>
<li><p>Check for overflow errors (yellow/black stripes) or unexpected scroll behavior.</p>
</li>
<li><p>Check accessibility: Scale fonts up/down, test with screen reader, check keyboard navigation in desktop mode.</p>
</li>
</ol>
<h2 id="heading-building-reusable-responsive-widgetscustom-widgets">Building Reusable Responsive Widgets/Custom Widgets</h2>
<p>One of the keys to scalable responsive UI is creating reusable widgets that encapsulate responsive behavior.</p>
<h4 id="heading-example-responsivetext-widget">Example: ResponsiveText Widget</h4>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_screenutil/flutter_screenutil.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ResponsiveText</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">final</span> <span class="hljs-built_in">String</span> text;
  <span class="hljs-keyword">final</span> FontWeight fontWeight;
  <span class="hljs-keyword">final</span> Color color;

  <span class="hljs-keyword">const</span> ResponsiveText(
    <span class="hljs-keyword">this</span>.text, {
    Key? key,
    <span class="hljs-keyword">this</span>.fontWeight = FontWeight.normal,
    <span class="hljs-keyword">this</span>.color = Colors.black,
  }) : <span class="hljs-keyword">super</span>(key: key);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Text(
      text,
      style: TextStyle(
        fontSize: <span class="hljs-number">16.</span>sp,         <span class="hljs-comment">// scaled font size</span>
        fontWeight: fontWeight,
        color: color,
      ),
    );
  }
}
</code></pre>
<p>Usage: Instead of manually specifying font size every time, you use <code>ResponsiveText</code>. Similarly, you can build <code>ResponsiveContainer</code>, <code>ResponsivePadding</code>, and so on. Encapsulating responsive logic in widgets improves code reuse and consistency.</p>
<h4 id="heading-example-breakpointawarelayout-widget">Example: BreakpointAwareLayout Widget</h4>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BreakpointAwareLayout</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">final</span> Widget mobile;
  <span class="hljs-keyword">final</span> Widget tablet;
  <span class="hljs-keyword">final</span> Widget desktop;

  <span class="hljs-keyword">const</span> BreakpointAwareLayout({
    Key? key,
    <span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.mobile,
    <span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.tablet,
    <span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.desktop,
  }) : <span class="hljs-keyword">super</span>(key: key);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> LayoutBuilder(
      builder: (context, constraints) {
        <span class="hljs-keyword">if</span> (constraints.maxWidth &gt;= <span class="hljs-number">1024</span>) {
          <span class="hljs-keyword">return</span> desktop;
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (constraints.maxWidth &gt;= <span class="hljs-number">600</span>) {
          <span class="hljs-keyword">return</span> tablet;
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-keyword">return</span> mobile;
        }
      },
    );
  }
}
</code></pre>
<p>Usage: You supply three versions of your UI and widget will choose based on width.</p>
<h2 id="heading-example-of-a-complete-sample-responsive-screen">Example of A Complete Sample Responsive Screen</h2>
<p>We’ll divide the example into these parts:</p>
<ol>
<li><p><strong>Project Setup and Imports</strong></p>
</li>
<li><p><strong>App Entry Point (</strong><code>main()</code> and <code>MyApp</code>)</p>
</li>
<li><p><strong>ScreenUtil Initialization</strong></p>
</li>
<li><p><strong>Main Page Layout (</strong><code>MyHomePage</code>)</p>
</li>
<li><p><strong>Adaptive Layout with</strong> <code>LayoutBuilder</code></p>
</li>
<li><p><strong>Main Content Builder (</strong><code>_buildMainContent</code>)</p>
</li>
<li><p><strong>Responsive Styling with</strong> <code>flutter_screenutil</code></p>
</li>
</ol>
<h3 id="heading-project-setup-and-imports"><strong>Project Setup and Imports</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_screenutil/flutter_screenutil.dart'</span>;

<span class="hljs-keyword">void</span> main() {
  runApp(MyApp());
}
</code></pre>
<h3 id="heading-app-entry-point-the-myapp-class"><strong>App Entry Point: The</strong> <code>MyApp</code> Class</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-comment">// Design size corresponds to the reference design (e.g., iPhone 6/7/8)</span>
  <span class="hljs-keyword">final</span> Size designSize = <span class="hljs-keyword">const</span> Size(<span class="hljs-number">360</span>, <span class="hljs-number">690</span>);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> ScreenUtilInit(
      designSize: designSize,
      minTextAdapt: <span class="hljs-keyword">true</span>,       <span class="hljs-comment">// adapts font size</span>
      splitScreenMode: <span class="hljs-keyword">true</span>,    <span class="hljs-comment">// supports split-screen</span>
      builder: (context, child) {
        <span class="hljs-keyword">return</span> MaterialApp(
          title: <span class="hljs-string">'Responsive Flutter Example'</span>,
          home: MyHomePage(),
        );
      },
    );
  }
}
</code></pre>
<h3 id="heading-the-responsive-home-screen-myhomepage"><strong>The Responsive Home Screen (</strong><code>MyHomePage</code>)</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyHomePage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">const</span> MyHomePage({Key? key}) : <span class="hljs-keyword">super</span>(key: key);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> <span class="hljs-built_in">double</span> screenWidth  = MediaQuery.of(context).size.width;
    <span class="hljs-keyword">final</span> <span class="hljs-built_in">double</span> screenHeight = MediaQuery.of(context).size.height;
    <span class="hljs-keyword">final</span> Orientation orientation = MediaQuery.of(context).orientation;

    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(
        title: Text(
          <span class="hljs-string">'Responsive UI'</span>,
          style: TextStyle(fontSize: <span class="hljs-number">20.</span>sp),
        ),
      ),
      body: SafeArea(
        child: LayoutBuilder(
          builder: (context, constraints) {
            <span class="hljs-keyword">if</span> (constraints.maxWidth &gt; <span class="hljs-number">600</span>) {
              <span class="hljs-comment">// Tablet/Desktop layout</span>
              <span class="hljs-keyword">return</span> Row(
                children: [
                  Expanded(
                    flex: <span class="hljs-number">2</span>,
                    child: Container(
                      color: Colors.blueGrey[<span class="hljs-number">50</span>],
                      child: Center(
                        child: Text(
                          <span class="hljs-string">'Sidebar Panel'</span>,
                          style: TextStyle(fontSize: <span class="hljs-number">18.</span>sp),
                        ),
                      ),
                    ),
                  ),
                  Expanded(
                    flex: <span class="hljs-number">5</span>,
                    child: Container(
                      padding: EdgeInsets.all(<span class="hljs-number">16.</span>w),
                      child: _buildMainContent(context),
                    ),
                  ),
                ],
              );
            } <span class="hljs-keyword">else</span> {
              <span class="hljs-comment">// Mobile layout</span>
              <span class="hljs-keyword">return</span> SingleChildScrollView(
                child: Padding(
                  padding: EdgeInsets.symmetric(horizontal: <span class="hljs-number">16.</span>w, vertical: <span class="hljs-number">24.</span>h),
                  child: _buildMainContent(context),
                ),
              );
            }
          },
        ),
      ),
    );
  }
}
</code></pre>
<h3 id="heading-building-the-core-content"><strong>Building the Core Content</strong></h3>
<pre><code class="lang-dart">Widget _buildMainContent(BuildContext context) {
  <span class="hljs-keyword">return</span> Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        <span class="hljs-string">'Welcome to the Responsive App'</span>,
        style: TextStyle(fontSize: <span class="hljs-number">24.</span>sp, fontWeight: FontWeight.bold),
      ),
      SizedBox(height: <span class="hljs-number">12.</span>h),
      Text(
        <span class="hljs-string">'This UI adapts to different screen sizes automatically. Try resizing your window or changing the orientation.'</span>,
        style: TextStyle(fontSize: <span class="hljs-number">16.</span>sp),
      ),
      SizedBox(height: <span class="hljs-number">24.</span>h),
      Row(
        children: [
          Expanded(
            child: Image.asset(
              <span class="hljs-string">'assets/sample.jpg'</span>,
              width: <span class="hljs-built_in">double</span>.infinity,
              height: <span class="hljs-number">200.</span>h,
              fit: BoxFit.cover,
            ),
          ),
        ],
      ),
      SizedBox(height: <span class="hljs-number">24.</span>h),
      Row(
        children: [
          Expanded(
            child: ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.symmetric(vertical: <span class="hljs-number">14.</span>h),
                textStyle: TextStyle(fontSize: <span class="hljs-number">16.</span>sp),
              ),
              child: Text(<span class="hljs-string">'Get Started'</span>),
            ),
          ),
        ],
      ),
    ],
  );
}
</code></pre>
<h2 id="heading-full-walkthrough-code-explained-in-depth">Full Walkthrough: Code Explained in Depth</h2>
<p>Let’s now go through a <strong>deep explanation</strong> of the full sample responsive Flutter screen, line by line and block by block.</p>
<h3 id="heading-imports-and-app-entry-point"><strong>Imports and App Entry Point</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_screenutil/flutter_screenutil.dart'</span>;

<span class="hljs-keyword">void</span> main() {
  runApp(MyApp());
}
</code></pre>
<h4 id="heading-explanation">Explanation:</h4>
<p><code>import 'package:flutter/material.dart';</code> brings in Flutter’s Material Design library, which contains essential UI widgets such as <code>Scaffold</code>, <code>AppBar</code>, <code>Text</code>, and <code>Column</code>. <code>import 'package:flutter_screenutil/flutter_screenutil.dart';</code> imports the <code>flutter_screenutil</code> package, providing scaling utilities like <code>.sp</code>, <code>.h</code>, <code>.w</code>, and <code>.r</code> that automatically adjust UI elements based on the device’s screen size. The <code>void main()</code> function serves as the entry point of the Flutter app, calling <code>runApp(MyApp())</code> to render the <code>MyApp</code> widget as the root of the application.</p>
<h3 id="heading-app-root-the-myapp-widget"><strong>App Root: The</strong> <code>MyApp</code> Widget</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-comment">// Design size corresponds to the reference design (e.g., iPhone 6/7/8)</span>
  <span class="hljs-keyword">final</span> Size designSize = <span class="hljs-keyword">const</span> Size(<span class="hljs-number">360</span>, <span class="hljs-number">690</span>);

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> ScreenUtilInit(
      designSize: designSize,
      minTextAdapt: <span class="hljs-keyword">true</span>,       <span class="hljs-comment">// adapts font size</span>
      splitScreenMode: <span class="hljs-keyword">true</span>,    <span class="hljs-comment">// supports split-screen</span>
      builder: (context, child) {
        <span class="hljs-keyword">return</span> MaterialApp(
          title: <span class="hljs-string">'Responsive Flutter Example'</span>,
          home: MyHomePage(),
        );
      },
    );
  }
}
</code></pre>
<h4 id="heading-explanation-1">Explanation:</h4>
<p><code>MyApp</code> extends <code>StatelessWidget</code>, meaning it doesn’t maintain any internal state and simply builds the widget tree. The <code>designSize</code> defines the base design resolution used in your design mockups (in this case, 360x690, typical of an iPhone 8). <code>ScreenUtilInit</code> initializes the <code>flutter_screenutil</code> package, and its parameters configure how responsiveness works: <code>designSize: Size(360, 690)</code> sets the reference design size for all scaling calculations, <code>minTextAdapt: true</code> ensures text automatically scales on smaller screens without clipping, and <code>splitScreenMode: true</code> maintains proper layout behavior in split-screen mode on devices like Android tablets. Inside its builder, it returns a <code>MaterialApp</code>, which defines the app’s title and sets <code>home: MyHomePage()</code>, the main screen displayed when the app launches.</p>
<p>So far, this part sets up the environment for responsive scaling.</p>
<h3 id="heading-the-home-screen-layout-myhomepage"><strong>The Home Screen Layout</strong> <code>MyHomePage</code></h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyHomePage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">const</span> MyHomePage({Key? key}) : <span class="hljs-keyword">super</span>(key: key);
</code></pre>
<p>The widget is <strong>stateless</strong>, meaning its layout does not depend on mutable state.</p>
<p>Inside <code>build(BuildContext context)</code>:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> <span class="hljs-built_in">double</span> screenWidth  = MediaQuery.of(context).size.width;
<span class="hljs-keyword">final</span> <span class="hljs-built_in">double</span> screenHeight = MediaQuery.of(context).size.height;
<span class="hljs-keyword">final</span> Orientation orientation = MediaQuery.of(context).orientation;
</code></pre>
<p>These three lines access <code>MediaQuery</code>, a Flutter API that provides information about the screen’s size, orientation, and other layout properties, where <code>screenWidth</code> represents the device’s current screen width, <code>screenHeight</code> represents its height, and <code>orientation</code> indicates whether the device is in portrait or landscape mode.</p>
<p>You’ll use these values to dynamically adjust your layout.</p>
<h3 id="heading-the-scaffold-and-appbar"><strong>The Scaffold and AppBar</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">return</span> Scaffold(
  appBar: AppBar(
    title: Text(
      <span class="hljs-string">'Responsive UI'</span>,
      style: TextStyle(fontSize: <span class="hljs-number">20.</span>sp),
    ),
  ),
</code></pre>
<h4 id="heading-explanation-2">Explanation:</h4>
<p><code>Scaffold</code> provides the basic structure of the page, including the app bar, body, and optional elements like a floating action button or drawer. Inside the <code>AppBar</code>, the title text uses <code>20.sp</code> instead of a fixed pixel value, <code>.sp</code> (scaled pixels) from <code>flutter_screenutil</code> ensures that the font size automatically adjusts to the screen’s pixel density and resolution, meaning a <code>20.sp</code> text appears smaller on compact screens and scales up proportionally on larger devices like tablets.</p>
<h3 id="heading-safearea-layoutbuilder"><strong>SafeArea + LayoutBuilder</strong></h3>
<pre><code class="lang-dart">body: SafeArea(
  child: LayoutBuilder(
    builder: (context, constraints) {
</code></pre>
<h4 id="heading-explanation-3">Explanation:</h4>
<p><code>SafeArea</code> ensures that content does not overlap with system UI areas such as the notch, status bar, or navigation gestures, while <code>LayoutBuilder</code> provides the constraints (maximum width and height) of the available space inside its parent, enabling the creation of responsive layouts that adapt dynamically to the screen’s actual size at runtime.</p>
<h3 id="heading-handling-large-and-small-screens"><strong>Handling Large and Small Screens</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (constraints.maxWidth &gt; <span class="hljs-number">600</span>) {
  <span class="hljs-comment">// Tablet/Desktop layout</span>
  <span class="hljs-keyword">return</span> Row(
    children: [
      Expanded(
        flex: <span class="hljs-number">2</span>,
        child: Container(
          color: Colors.blueGrey[<span class="hljs-number">50</span>],
          child: Center(
            child: Text(
              <span class="hljs-string">'Sidebar Panel'</span>,
              style: TextStyle(fontSize: <span class="hljs-number">18.</span>sp),
            ),
          ),
        ),
      ),
      Expanded(
        flex: <span class="hljs-number">5</span>,
        child: Container(
          padding: EdgeInsets.all(<span class="hljs-number">16.</span>w),
          child: _buildMainContent(context),
        ),
      ),
    ],
  );
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// Mobile layout</span>
  <span class="hljs-keyword">return</span> SingleChildScrollView(
    child: Padding(
      padding: EdgeInsets.symmetric(horizontal: <span class="hljs-number">16.</span>w, vertical: <span class="hljs-number">24.</span>h),
      child: _buildMainContent(context),
    ),
  );
}
</code></pre>
<h4 id="heading-explanation-4">Explanation:</h4>
<p>This block handles responsive breakpoints by determining how the UI adapts to different screen widths. If <code>constraints.maxWidth &gt; 600</code>, the layout is treated as a tablet or desktop view. In this case, the UI uses a <code>Row</code> to divide the screen horizontally, with <code>Expanded(flex: 2)</code> creating a sidebar that takes two parts of the available width, and <code>Expanded(flex: 5)</code> creating the main content area that takes five parts, maintaining a 2:5 ratio. The sidebar displays “Sidebar Panel,” representing where side navigation or additional panels can appear on larger screens. For smaller screens (phones), the layout switches to a vertical arrangement using <code>SingleChildScrollView</code> to enable scrolling, with padding applied through scaled spacing (<code>16.w</code> horizontally and <code>24.h</code> vertically). The <code>_buildMainContent()</code> function is reused to keep content logic consistent across all layouts.</p>
<h3 id="heading-building-the-core-content-1"><strong>Building the Core Content</strong></h3>
<pre><code class="lang-dart">Widget _buildMainContent(BuildContext context) {
  <span class="hljs-keyword">return</span> Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Text(
        <span class="hljs-string">'Welcome to the Responsive App'</span>,
        style: TextStyle(fontSize: <span class="hljs-number">24.</span>sp, fontWeight: FontWeight.bold),
      ),
      SizedBox(height: <span class="hljs-number">12.</span>h),
      Text(
        <span class="hljs-string">'This UI adapts to different screen sizes automatically. Try resizing your window or changing the orientation.'</span>,
        style: TextStyle(fontSize: <span class="hljs-number">16.</span>sp),
      ),
      SizedBox(height: <span class="hljs-number">24.</span>h),
      Row(
        children: [
          Expanded(
            child: Image.asset(
              <span class="hljs-string">'assets/sample.jpg'</span>,
              width: <span class="hljs-built_in">double</span>.infinity,
              height: <span class="hljs-number">200.</span>h,
              fit: BoxFit.cover,
            ),
          ),
        ],
      ),
      SizedBox(height: <span class="hljs-number">24.</span>h),
      Row(
        children: [
          Expanded(
            child: ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.symmetric(vertical: <span class="hljs-number">14.</span>h),
                textStyle: TextStyle(fontSize: <span class="hljs-number">16.</span>sp),
              ),
              child: Text(<span class="hljs-string">'Get Started'</span>),
            ),
          ),
        ],
      ),
    ],
  );
}
</code></pre>
<h4 id="heading-explanation-5">Explanation:</h4>
<p>This method builds the actual visible content of the app. It uses a <code>Column</code> to stack widgets vertically, with <code>crossAxisAlignment: CrossAxisAlignment.start</code> aligning all child widgets to the start of the horizontal axis (left side in LTR layouts). Text widgets use <code>.sp</code> for responsive scaling, applying a larger font size (24.sp) for the title and a smaller, comfortable one (16.sp) for the body. <code>SizedBox</code> provides vertical spacing (<code>12.h</code> or <code>24.h</code>), where <code>.h</code> scales proportionally to the screen height. A <code>Row</code> containing <code>Image.asset</code> uses <code>Expanded</code> to make the image fill the available width, with <code>fit: BoxFit.cover</code> ensuring the image fills its container correctly and <code>height: 200.h</code> allowing dynamic height scaling. Another <code>Row</code> contains an <code>ElevatedButton</code> that spans the available width through <code>Expanded</code>, with padding and font size scaling via <code>EdgeInsets.symmetric(vertical: 14.h)</code> and <code>TextStyle(fontSize: 16.sp)</code>. Overall, the <code>_buildMainContent()</code> method produces a clean, scalable, and responsive layout that maintains visual consistency across all devices.</p>
<h3 id="heading-why-this-works"><strong>Why This Works</strong></h3>
<p><code>LayoutBuilder</code> gives the parent constraints, letting you conditionally render different layouts for mobile and large screens. <code>ScreenUtil</code> ensures that all elements (text, padding, sizes) adapt proportionally. <code>MediaQuery</code> can be used if you need real-time adaptation based on device rotation, size, or padding. <code>SafeArea</code> prevents clipping under system UI areas.</p>
<p>Together, these techniques combine <strong>Flutter’s native flexibility</strong> with <strong>ScreenUtil’s scaling power</strong>, making the UI dynamic, elegant, and consistent across all platforms.</p>
<h2 id="heading-key-takeaways"><strong>Key Takeaways</strong></h2>
<ol>
<li><p>Always design with a <strong>reference size</strong> and scale up/down with <code>flutter_screenutil</code>.</p>
</li>
<li><p>Use <code>LayoutBuilder</code> or <code>MediaQuery</code> for breakpoints.</p>
</li>
<li><p>Test layouts in <strong>portrait/landscape</strong> and across <strong>small/large screens</strong>.</p>
</li>
<li><p>Avoid hardcoded pixel values, use <code>.sp</code>, <code>.w</code>, <code>.h</code> instead.</p>
</li>
<li><p>Keep your content modular with helper functions like <code>_buildMainContent()</code>.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating responsive and adaptive UIs in Flutter is not just about making things “look okay” on different devices, it’s about crafting <strong>fluid, consistent</strong>, and <strong>usable</strong> experiences regardless of screen size, orientation or platform. By leveraging Flutter’s built-in layout widgets (<code>Row</code>, <code>Column</code>, <code>Flexible</code>, <code>Expanded</code>, <code>LayoutBuilder</code>), and coupling them with screen-aware APIs (<code>MediaQuery</code>, <code>SafeArea</code>, etc) and specialized packages (like <code>flutter_screenutil</code>), you can build apps that scale beautifully.</p>
<p>Key takeaways:</p>
<ul>
<li><p>Think <strong>flexibility</strong> first: avoid rigid sizing.</p>
</li>
<li><p>Use screen size/constraints to decide layout variations (instead of device type).</p>
</li>
<li><p>Scale typography, images, paddings to maintain usability and aesthetics.</p>
</li>
<li><p>Always test on multiple devices/sizes/orientations.</p>
</li>
<li><p>Encapsulate responsive logic in reusable widgets to keep your code clean and maintainable.</p>
</li>
</ul>
<p>With these practices in hand, you’ll be well-equipped to deliver visually stunning, well-performing, and truly responsive Flutter applications for 2024 and beyond.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><p>“Adaptive and responsive design in Flutter”, Flutter Docs. (<a target="_blank" href="https://docs.flutter.dev/ui/adaptive-responsive">Flutter Docs</a>)</p>
</li>
<li><p>“Building Responsive UIs in Flutter: Tips and Best Practices”. TheOneTechnologies blog. (<a target="_blank" href="https://theonetechnologies.com/blog/post/building-responsive-ui-in-flutter-tips-and-best-practices">TheOneTechnologies</a>)</p>
</li>
<li><p>“Best strategy to implement responsive design : r/FlutterDev”, Reddit discussion. (<a target="_blank" href="https://www.reddit.com/r/FlutterDev/comments/192sqg5/best_strategy_to_implement_responsive_design">Reddit</a>)</p>
</li>
<li><p>“How to Make a Flutter App Responsive for Different Mobile Screen Sizes”, StackOverflow Q&amp;A. (<a target="_blank" href="https://stackoverflow.com/questions/79539122/how-to-make-a-flutter-app-responsive-for-different-mobile-screen-sizes">Stack Overflow</a>)</p>
</li>
<li><p>“5 Best Practices to Build Robust and Responsive UIs in Flutter”, Somnio Software blog. (<a target="_blank" href="https://somniosoftware.com/blog/5-best-practices-to-build-robust-and-responsive-uis-in-flutter">somniosoftware.com</a>)</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Improve User Experience with Optimistic UI and SWR ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever noticed how some apps feel like they can read your mind? You click a button, and before you can even blink, it's done – no loading screens, no waiting around. It's like magic, right? Well, let me tell you a little secret: that's the pow... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/improve-user-experience-with-optimistic-ui-swr/</link>
                <guid isPermaLink="false">66bb8911b0d3ac3d7acde3db</guid>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Jaja ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jul 2024 22:33:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/Article-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever noticed how some apps feel like they can read your mind? You click a button, and before you can even blink, it's done – no loading screens, no waiting around. It's like magic, right? Well, let me tell you a little secret: that's the power of Optimistic UI.</p>
<p>In this article, we'll dive into Optimistic UI and explore how it works and keeps your web experience smooth as butter. We'll build a simple task app together that'll show how Optimistic UI can help turn mundane tasks into lightning-fast interactions that leave your users feeling happy.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Fundamentals of JavaScript and React</li>
<li>Fundamentals of Async programming and Axios</li>
<li>Knowledge of hook-oriented fetch libraries would also be beneficial</li>
</ul>
<h2 id="heading-what-well-cover"><strong>What We'll Cover:</strong></h2>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-optimistic-ui">What is Optimistic UI?</a></li>
<li><a class="post-section-overview" href="#heading-why-does-optimistic-ui-matter">Why Does Optimistic UI Matter?</a></li>
<li><a class="post-section-overview" href="#heading-other-benefits-of-optimistic-ui">Other Benefits of Optimistic UI</a></li>
<li><a class="post-section-overview" href="#heading-introducing-swr-stale-while-revalidate">Introducing SWR: Stale-While-Revalidate</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-the-environment">How to Set Up the Environment</a></li>
<li><a class="post-section-overview" href="#building-the-task-app-ui">How to Build the Task App UI</a><br>– <a class="post-section-overview" href="#heading-regular-crud-ui">Regular CRUD UI</a><br>– <a class="post-section-overview" href="#heading-optimistic-crud-ui">Optimistic CRUD UI</a></li>
<li><a class="post-section-overview" href="#heading-drawbacks-of-optimistic-ui">Drawbacks of Optimistic UI</a></li>
<li><a class="post-section-overview" href="#heading-ideal-use-cases-for-optimistic-ui">Ideal Use Cases for Optimistic UI</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-is-optimistic-ui">What is Optimistic UI?</h2>
<p>At its core, Optimistic UI is all about keeping your app feeling snappy and responsive, even when a lot is happening behind the scenes. It's like having a superpower that lets your app predict the future – well, sort of.</p>
<p>When you perform an action in your app – whether it's adding a new item to a list or updating a profile – Optimistic UI kicks in to make it happen right away, without waiting for confirmation from the server. It's the ultimate optimist, always assuming everything will work out just fine.</p>
<h2 id="heading-why-does-optimistic-ui-matter">Why Does Optimistic UI Matter?</h2>
<p>So why should you care about Optimistic UI? Simple: because it's the secret sauce that turns good apps into great ones. </p>
<p>Think about it: when you click a button, you expect something to happen – and you expect it to happen fast. That's where Optimistic UI shines. By giving your users instant feedback and keeping your app feeling snappy, Optimistic UI enhances the overall user experience. </p>
<p>No more staring at loading screens or wondering if your click <em>actually</em> did anything – with Optimistic UI, every action feels easy and effective.</p>
<h2 id="heading-other-benefits-of-optimistic-ui">Other Benefits of Optimistic UI</h2>
<ol>
<li><strong>Reduced Perceived Latency</strong>: Optimistic UI reduces the perceived latency of actions by displaying changes immediately without waiting for server confirmation. This creates a perception of faster response times, even if server communication takes longer.</li>
<li><strong>Improved Responsiveness</strong>: Optimistic UI allows users to interact with the app continuously without interruptions from loading spinners or waiting screens. This uninterrupted flow enhances the overall responsiveness of the application.</li>
<li><strong>Support for Complex Interactions</strong>: Optimistic UI helps complex interactions, such as drag-and-drop, multi-step processes, and real-time collaboration, feel fluid and intuitive. This flexibility opens up possibilities for innovative features and functionalities in the app.</li>
<li><strong>Increased User Engagement</strong>: The responsiveness and interactivity provided by Optimistic UI can lead to increased user engagement and retention. Users are more likely to return to an app that provides a smooth and enjoyable experience.</li>
</ol>
<h2 id="heading-introducing-swr-stale-while-revalidate">Introducing SWR: Stale-While-Revalidate</h2>
<p>Before we dive into the implementation, let's take a moment to talk about SWR. SWR is a lightweight React Hook library for data fetching. SWR stands for <a target="_blank" href="https://swr.vercel.app/examples/optimistic-ui">Stale-While-Revalidate</a>, and it strikes the perfect balance between performance and freshness when fetching data in your React applications.</p>
<p>SWR also automatically revalidates data in the background while still serving stale data from the cache. This means your app stays fast and responsive, even when fetching fresh data from the server.</p>
<p>But that's not all – SWR also supports key features like caching, pagination, and error handling, making it a powerful tool in your arsenal for building fast, reliable web applications as well as implementing Optimistic UI.</p>
<h2 id="heading-how-to-set-up-the-environment">How to Set Up the Environment</h2>
<p>I've prepared a GitHub repository with starter files to speed things up. Simply <a target="_blank" href="https://github.com/Daiveedjay/Optimistic-UI-with-SWR/tree/starter">clone this repo</a> and install the dependencies.</p>
<p>The starter code consists of the basic JSX components required, as well as some basic <a target="_blank" href="https://axios-http.com/docs/intro">Axios</a> functions for performing CRUD operations. After installing all the necessary packages with <code>npm i</code>, open your terminal and start up your local endpoint using <a target="_blank" href="https://www.npmjs.com/package/json-server">json-server</a>.</p>
<pre><code class="lang-bash">npx json-server data/db.json -p 3500
</code></pre>
<p>To see all your data present, head over to that route:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/1-Showing-initial-data.png" alt="Image" width="600" height="400" loading="lazy">
<em>Showing initial data</em></p>
<h2 id="heading-how-to-build-the-task-app-ui">How to Build the Task App UI</h2>
<p>In this section, we’ll first implement CRUD applications without Optimistic UI and then with Optimistic UI to show the differences between them.</p>
<h3 id="heading-regular-crud-ui">Regular CRUD UI</h3>
<p>Start by heading over to your <code>TaskContainer</code> component, then use the <code>useSWR</code> hook to call your fetch function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {
    isLoading,
    error,
    <span class="hljs-attr">data</span>: tasks,
    mutate,
  } = useSWR(cacheKey, fetchTasks, {
    <span class="hljs-attr">onSuccess</span>: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span>
      data.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(b.createdAt) - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(a.createdAt)),
  });
</code></pre>
<p>SWR uses a similar data fetching hook and pattern to other libraries such as <a target="_blank" href="https://tanstack.com/query/latest/docs/framework/react/overview">React Query (TanStack Query)</a> and <a target="_blank" href="https://redux-toolkit.js.org/rtk-query/overview">Redux Toolkit Query</a>. This hook fetching pattern often returns a loading state, an error state, your fetched data (if any) and a mutation function (but more about that later).</p>
<p><strong>Note</strong>: The <code>cacheKey</code> is a unique key used to notify SWR when and where to re-call your function. The <code>onSuccess</code> function is a method used to trigger another action when the fetch is successful – in this case, sorting the data in descending order.</p>
<p>With your data back, you can now create the JSX markup.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">return</span> (

      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-8 p-4"</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-4 shadow-lg "</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-4 "</span>&gt;</span>
            {tasks &amp;&amp;
              tasks.map((task, index) =&gt; {
                return (
                  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
                    <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-4 items-center py-2 px-6 rounded-md bg-[#74a0a6]"</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">label</span>
                        <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                        <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                        <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">flex</span> <span class="hljs-attr">gap-4</span> <span class="hljs-attr">text-</span>[<span class="hljs-attr">14px</span>] <span class="hljs-attr">items-center</span> <span class="hljs-attr">font-bold</span> <span class="hljs-attr">list-none</span> <span class="hljs-attr">p-4</span> <span class="hljs-attr">rounded</span> <span class="hljs-attr">bg-</span>[#<span class="hljs-attr">88adb3</span>] <span class="hljs-attr">cursor-pointer</span> <span class="hljs-attr">hover:bg-</span>[#<span class="hljs-attr">609299</span>]`}&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"inline-flex items-center"</span>&gt;</span>
                          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                            <span class="hljs-attr">className</span>=<span class="hljs-string">"relative flex items-center p-3 rounded-full cursor-pointer"</span>
                            <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"checkbox"</span>&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                              <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
                              <span class="hljs-attr">name</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                              <span class="hljs-attr">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                              <span class="hljs-attr">className</span>=<span class="hljs-string">"before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-md border border-[#edebd9] transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-lines checked:bg-[#545240] checked:before:bg-[#edebd9] hover:before:opacity-10 before:checked:hover:before:opacity-10 "</span>
                              <span class="hljs-attr">checked</span>=<span class="hljs-string">{task.completed}</span>
                                                         /&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"absolute transition-opacity opacity-0 pointer-events-none text-stone-100 top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100"</span>&gt;</span>
                              <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
                                <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
                                <span class="hljs-attr">className</span>=<span class="hljs-string">"h-3.5 w-3.5"</span>
                                <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 20 20"</span>
                                <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span>
                                <span class="hljs-attr">stroke</span>=<span class="hljs-string">"currentColor"</span>
                                <span class="hljs-attr">strokeWidth</span>=<span class="hljs-string">"1"</span>&gt;</span>
                                <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
                                  <span class="hljs-attr">fillRule</span>=<span class="hljs-string">"evenodd"</span>
                                  <span class="hljs-attr">d</span>=<span class="hljs-string">"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"</span>
                                  <span class="hljs-attr">clipRule</span>=<span class="hljs-string">"evenodd"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span>
                              <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
                            <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                          <span class="hljs-tag">&lt;/<span class="hljs-name">label</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">label</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> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl font-bold text-[#161515] "</span>&gt;</span>
                        {task.title}
                      <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm font-semibold text-[#42403f] "</span>&gt;</span>
                        {task.description}
                      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-2 mt-2 text-xs font-bold"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center "</span>&gt;</span>
                          <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
                            <span class="hljs-attr">src</span>=<span class="hljs-string">{userImages[index]}</span>
                            <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>
                            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-10 h-10 rounded-full "</span>
                          /&gt;</span>
                          <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span> {task.assignedTo}<span class="hljs-tag">&lt;/<span class="hljs-name">span</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">className</span>=<span class="hljs-string">"p-2 ml-auto rounded-full cursor-pointer hover:bg-red-300"</span>
                    &gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">FaTrash</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"#545240"</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>

  );
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/2-UI-after-fetcing-data.png" alt="Image" width="600" height="400" loading="lazy">
<em>UI after data fetching</em></p>
<p>After that, head into your <code>Taskform</code> component and create a form UI for creating new tasks.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { addSingleTask } <span class="hljs-keyword">from</span> <span class="hljs-string">"./services/api"</span>;
<span class="hljs-keyword">import</span> toast <span class="hljs-keyword">from</span> <span class="hljs-string">"react-hot-toast"</span>;
<span class="hljs-keyword">import</span> { useState } <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">Taskform</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [description, setDescription] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [assignedTo, setAssignedTo] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-[#74a0a6] p-4 rounded-md"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col w-full gap-2 "</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"title"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Title<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{title}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setTitle(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"description"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Description<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{description}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setDescription(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"assignedTo"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Assigned To<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{assignedTo}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setAssignedTo(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-2 mt-3 border text-white rounded-md w-max hover:bg-white hover:text-[#74a0a6]"</span>&gt;</span>
          Add
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</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">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>After that, import it into your <code>TaskContainer</code> component.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">return</span> (

      &lt;div className="flex flex-col gap-8 p-4"&gt;
        &lt;Taskform /&gt;
        &lt;div className="p-4 shadow-lg "&gt;
          &lt;div className="flex flex-col gap-4 "&gt;
            {tasks &amp;&amp;
              tasks.map((task, index) =&gt; {
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/3-UI-with-Form-added.png" alt="Image" width="600" height="400" loading="lazy">
<em>UI with Form added</em></p>
<p>To add a new task, create a handler function in the <code>Taskform</code>, then import your <code>POST</code> function from your API file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> addTaskMutation = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();
    <span class="hljs-keyword">const</span> createdAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString(); <span class="hljs-comment">// Get current timestamp as a string</span>

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> addSingleTask({
        title,
        description,
        assignedTo,
        <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>,
        createdAt,
      });

      toast.success(<span class="hljs-string">"Task added succesfully."</span>);
      setTitle(<span class="hljs-string">""</span>);
      setDescription(<span class="hljs-string">""</span>);
      setAssignedTo(<span class="hljs-string">""</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to add the new task."</span>);
    }
  };
</code></pre>
<p>Finally, call the <code>mutate</code> function after your <code>POST</code> function call to enable SWR to invalidate your current data and make a new request. You can get this mutate function from the <code>useSWR</code> hook in the <code>TaskContainer</code>, then pass it through props to the form.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> {
    isLoading,
    error,
    <span class="hljs-attr">data</span>: tasks,
    mutate,
  } = useSWR(cacheKey, fetchTasks, {
    <span class="hljs-attr">onSuccess</span>: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span>
      data.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(b.createdAt) - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(a.createdAt)),
  });
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-8 p-4"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Taskform</span> <span class="hljs-attr">mutate</span>=<span class="hljs-string">{mutate}</span> /&gt;</span></span>
</code></pre>
<p>Then call it in the <code>TaskForm</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { addSingleTask } <span class="hljs-keyword">from</span> <span class="hljs-string">"./services/api"</span>;
<span class="hljs-keyword">import</span> toast <span class="hljs-keyword">from</span> <span class="hljs-string">"react-hot-toast"</span>;
<span class="hljs-keyword">import</span> { useState } <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">Taskform</span>(<span class="hljs-params">{ mutate }</span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [description, setDescription] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [assignedTo, setAssignedTo] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> addTaskMutation = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();
    <span class="hljs-keyword">const</span> createdAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString();
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> addSingleTask({
        title,
        description,
        assignedTo,
        <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>,
        createdAt,
      });
      mutate();

      toast.success(<span class="hljs-string">"Task added succesfully."</span>);
      setTitle(<span class="hljs-string">""</span>);
      setDescription(<span class="hljs-string">""</span>);
      setAssignedTo(<span class="hljs-string">""</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to add the new task."</span>);
    }
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-[#74a0a6] p-4 rounded-md"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col w-full gap-2 "</span>
        <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{(e)</span> =&gt;</span> addTaskMutation(e)}&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"title"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Title<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{title}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setTitle(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"description"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Description<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{description}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setDescription(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"assignedTo"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold "</span>&gt;</span>Assigned To<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full font-medium  focus:outline-[#74a0a6] focus-within:outline-[#74a0a6] p-1 bg-transparent border rounded-md"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{assignedTo}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setAssignedTo(e.target.value)}
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-2 mt-3 border text-white rounded-md w-max hover:bg-white hover:text-[#74a0a6]"</span>&gt;</span>
          Add
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</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">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Testing your component now gives the following result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/1-Regular-Create-Operation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Regular Create Operation</em></p>
<p>As you can see, the list is updated after each form submission. But this still doesn’t highlight our need for optimistic UI. You’re probably thinking, if the operation happened that fast, why bother with Optimistic UI?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/2-What-s-the-point.gif" alt="Image" width="600" height="400" loading="lazy">
<em>What's the point gif</em></p>
<p>Well, for starters, no real-world application is ever going to beat the speed of your local JSON server, as the data is readily available to you and users often have unstable network connections.</p>
<p>Let's slow down the fetch to illustrate a real-world data request better. This better simulates a real-world scenario as users often come from different locations that have varying internet speeds.</p>
<p>Start by creating a delay function that runs before each of your function calls.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> tasksApi = axios.create({
  <span class="hljs-attr">baseURL</span>: <span class="hljs-string">"http://localhost:3500"</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> tasksUrlEndpoint = <span class="hljs-string">"/tasks"</span>;

<span class="hljs-keyword">const</span> delay = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> res(), <span class="hljs-number">1200</span>));

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> fetchTasks = <span class="hljs-keyword">async</span> () =&gt; {
   <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> tasksApi.get(tasksUrlEndpoint);
  <span class="hljs-keyword">return</span> response.data;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addSingleTask = <span class="hljs-keyword">async</span> ({
  title,
  description,
  completed,
  assignedTo,
  createdAt,
}) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> tasksApi.post(tasksUrlEndpoint, {
    title,
    description,
    completed,
    assignedTo,
    createdAt,
  });
  <span class="hljs-keyword">return</span> response.data;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateSingleTask = <span class="hljs-keyword">async</span> (task) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> tasksApi.patch(<span class="hljs-string">`<span class="hljs-subst">${tasksUrlEndpoint}</span>/<span class="hljs-subst">${task.id}</span>`</span>, task);
  <span class="hljs-keyword">return</span> response.data;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> deleteSingleTask = <span class="hljs-keyword">async</span> ({ id }) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> tasksApi.delete(<span class="hljs-string">`<span class="hljs-subst">${tasksUrlEndpoint}</span>/<span class="hljs-subst">${id}</span>`</span>, id);
};
</code></pre>
<p>Then attempt your create operation again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/3-Create-operation-after-delay.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Create operation after delay</em></p>
<p>As you may have noticed, the create operation was only fired after the delay function (spanning 1.2 seconds) finished running, which caused a brief spell of inactivity on the screen. </p>
<p>The usual way to handle those periods between loading is usually a loading spinner or indicator telling you that some background activity is running. But this often disrupts your flow when working in the application, and quite frankly is disappointing.</p>
<p>The same static effect can be seen in the update operation, where users have to wait for server confirmation to see fresh data.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> updateTaskMutation = <span class="hljs-keyword">async</span> (updatedTask) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> updateSingleTask(updatedTask);
      mutate();
      toast.success(<span class="hljs-string">"Successfully updated task"</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to update the task."</span>);
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-8 p-4"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Taskform</span> <span class="hljs-attr">mutate</span>=<span class="hljs-string">{mutate}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-4 shadow-lg "</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-4 "</span>&gt;</span>
          {tasks &amp;&amp;
            tasks.map((task, index) =&gt; {
              return (
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
                  <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                  <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-4 items-center py-2 px-6 rounded-md bg-[#74a0a6]"</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">label</span>
                      <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                      <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                      <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">flex</span> <span class="hljs-attr">gap-4</span> <span class="hljs-attr">text-</span>[<span class="hljs-attr">14px</span>] <span class="hljs-attr">items-center</span> <span class="hljs-attr">font-bold</span> <span class="hljs-attr">list-none</span> <span class="hljs-attr">p-4</span> <span class="hljs-attr">rounded</span> <span class="hljs-attr">bg-</span>[#<span class="hljs-attr">88adb3</span>] <span class="hljs-attr">cursor-pointer</span> <span class="hljs-attr">hover:bg-</span>[#<span class="hljs-attr">609299</span>]`}&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"inline-flex items-center"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                          <span class="hljs-attr">className</span>=<span class="hljs-string">"relative flex items-center p-3 rounded-full cursor-pointer"</span>
                          <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"checkbox"</span>&gt;</span>
                          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                            <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
                            <span class="hljs-attr">name</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                            <span class="hljs-attr">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                            <span class="hljs-attr">className</span>=<span class="hljs-string">"before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-md border border-[#edebd9] transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-lines checked:bg-[#545240] checked:before:bg-[#edebd9] hover:before:opacity-10 before:checked:hover:before:opacity-10 "</span>
                            <span class="hljs-attr">checked</span>=<span class="hljs-string">{task.completed</span> === <span class="hljs-string">true}</span>
                            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{()</span> =&gt;</span>
                              updateTaskMutation({
                                ...task,
                                completed: !task.completed,
                              })
                            }
                          /&gt;
                          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"absolute transition-opacity opacity-0 pointer-events-none text-stone-100 top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100"</span>&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
                              <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
                              <span class="hljs-attr">className</span>=<span class="hljs-string">"h-3.5 w-3.5"</span>
                              <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 20 20"</span>
                              <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span>
                              <span class="hljs-attr">stroke</span>=<span class="hljs-string">"currentColor"</span>
                              <span class="hljs-attr">strokeWidth</span>=<span class="hljs-string">"1"</span>&gt;</span>
                              <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
                                <span class="hljs-attr">fillRule</span>=<span class="hljs-string">"evenodd"</span>
                                <span class="hljs-attr">d</span>=<span class="hljs-string">"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"</span>
                                <span class="hljs-attr">clipRule</span>=<span class="hljs-string">"evenodd"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span>
                            <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
                          <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-name">label</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">label</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> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl font-bold text-[#161515] "</span>&gt;</span>
                      {task.title}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm font-semibold text-[#42403f] "</span>&gt;</span>
                      {task.description}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-2 mt-2 text-xs font-bold"</span>&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center "</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
                          <span class="hljs-attr">src</span>=<span class="hljs-string">{userImages[index]}</span>
                          <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>
                          <span class="hljs-attr">className</span>=<span class="hljs-string">"w-10 h-10 rounded-full "</span>
                        /&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span> {task.assignedTo}<span class="hljs-tag">&lt;/<span class="hljs-name">span</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">className</span>=<span class="hljs-string">"p-2 ml-auto rounded-full cursor-pointer hover:bg-red-300"</span>
                   &gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">FaTrash</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"#545240"</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>
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/4-Update-operation-after-delay.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Update operation after delay</em></p>
<p>And in the delete operation, which also waits for server conformation to rehydrate the page.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> deleteTaskMutation = <span class="hljs-keyword">async</span> ({ id }) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> deleteSingleTask({ id });
      mutate();
      toast.success(<span class="hljs-string">"Successfully deleted task"</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to delete the task."</span>);
    }
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-8 p-4"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Taskform</span> <span class="hljs-attr">mutate</span>=<span class="hljs-string">{mutate}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-4 shadow-lg "</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col gap-4 "</span>&gt;</span>
          {tasks &amp;&amp;
            tasks.map((task, index) =&gt; {
              return (
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
                  <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                  <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-4 items-center py-2 px-6 rounded-md bg-[#74a0a6]"</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">label</span>
                      <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                      <span class="hljs-attr">key</span>=<span class="hljs-string">{task.id}</span>
                      <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">flex</span> <span class="hljs-attr">gap-4</span> <span class="hljs-attr">text-</span>[<span class="hljs-attr">14px</span>] <span class="hljs-attr">items-center</span> <span class="hljs-attr">font-bold</span> <span class="hljs-attr">list-none</span> <span class="hljs-attr">p-4</span> <span class="hljs-attr">rounded</span> <span class="hljs-attr">bg-</span>[#<span class="hljs-attr">88adb3</span>] <span class="hljs-attr">cursor-pointer</span> <span class="hljs-attr">hover:bg-</span>[#<span class="hljs-attr">609299</span>]`}&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"inline-flex items-center"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                          <span class="hljs-attr">className</span>=<span class="hljs-string">"relative flex items-center p-3 rounded-full cursor-pointer"</span>
                          <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"checkbox"</span>&gt;</span>
                          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                            <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
                            <span class="hljs-attr">name</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                            <span class="hljs-attr">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-</span>${<span class="hljs-attr">task.id</span>}`}
                            <span class="hljs-attr">className</span>=<span class="hljs-string">"before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-md border border-[#edebd9] transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-lines checked:bg-[#545240] checked:before:bg-[#edebd9] hover:before:opacity-10 before:checked:hover:before:opacity-10 "</span>
                            <span class="hljs-attr">checked</span>=<span class="hljs-string">{task.completed</span> === <span class="hljs-string">true}</span>
                            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{()</span> =&gt;</span>
                              updateTaskMutation({
                                ...task,
                                completed: !task.completed,
                              })
                            }
                          /&gt;
                          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"absolute transition-opacity opacity-0 pointer-events-none text-stone-100 top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100"</span>&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
                              <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
                              <span class="hljs-attr">className</span>=<span class="hljs-string">"h-3.5 w-3.5"</span>
                              <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 20 20"</span>
                              <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span>
                              <span class="hljs-attr">stroke</span>=<span class="hljs-string">"currentColor"</span>
                              <span class="hljs-attr">strokeWidth</span>=<span class="hljs-string">"1"</span>&gt;</span>
                              <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
                                <span class="hljs-attr">fillRule</span>=<span class="hljs-string">"evenodd"</span>
                                <span class="hljs-attr">d</span>=<span class="hljs-string">"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"</span>
                                <span class="hljs-attr">clipRule</span>=<span class="hljs-string">"evenodd"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span>
                            <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
                          <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-name">label</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">label</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> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl font-bold text-[#161515] "</span>&gt;</span>
                      {task.title}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm font-semibold text-[#42403f] "</span>&gt;</span>
                      {task.description}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex gap-2 mt-2 text-xs font-bold"</span>&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center "</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
                          <span class="hljs-attr">src</span>=<span class="hljs-string">{userImages[index]}</span>
                          <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span>
                          <span class="hljs-attr">className</span>=<span class="hljs-string">"w-10 h-10 rounded-full "</span>
                        /&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span> {task.assignedTo}<span class="hljs-tag">&lt;/<span class="hljs-name">span</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">className</span>=<span class="hljs-string">"p-2 ml-auto rounded-full cursor-pointer hover:bg-red-300"</span>
                    <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> deleteTaskMutation({ id: task.id })}&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">FaTrash</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"#545240"</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>
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/5-Delete-operation-after-delay.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Delete operation after delay</em></p>
<p>These few seconds of inactivity or loading can impact the level of satisfaction users get from your application, which is why we’re going to use Optimistic UI to fix it.</p>
<h3 id="heading-optimistic-crud-ui">Optimistic CRUD UI</h3>
<p>The way this works in practical terms is that, when you perform an action, it immediately adds to your UI state (cache) while the async operation is running in the background.</p>
<p>If the operation is successful, nothing on the UI changes and everything acts like it worked on the first try. But if it fails, the UI state reverts to its previous state and an error is displayed via your toast.</p>
<p>An optimistic UI approach offers a much better user experience than traditional loading messages or spinners. When you see an immediate response after clicking a button, the app feels faster and more responsive, keeping you engaged and satisfied. You can continue interacting with the app seamlessly, without waiting for server confirmations, making the experience smoother and more intuitive.</p>
<p>This immediate feedback reduces your perceived wait time and keeps the interface visually stable, avoiding annoying flickers or sudden changes. Plus, when the app feels this responsive, you're more likely to keep using it and have a positive experience.</p>
<p>On the flip side, loading messages or spinners can interrupt your flow, making the app feel slower and potentially frustrating you.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Group-369-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Optimistic UI diagram</em></p>
<p>It still sounds a little like gibberish, eh? Well, let’s learn as we go!</p>
<p>In your <code>swrAPI</code> file, create another mutation function. This function takes in two parameters: the new task you want to add and the list of already existing tasks.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addTaskMutation = <span class="hljs-keyword">async</span> (newTask, tasks) =&gt; {
  };
</code></pre>
<p>Then it uses your already existing <code>create</code> function to attempt to create a new task. After this, you store the result and return that result in a new array, together with the already existing tasks.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addTaskMutation = <span class="hljs-keyword">async</span> (newTask, tasks) =&gt; {
  <span class="hljs-keyword">const</span> addedTask = <span class="hljs-keyword">await</span> addSingleTask(newTask);
  <span class="hljs-keyword">return</span> [...tasks, addedTask].sort(
    <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(b.createdAt) - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(a.createdAt)
  );
};
</code></pre>
<p>As you would suspect, this function does the same as the previous <code>create</code> function we wrote, but it’s what comes next that we’re after.</p>
<p>Next, create an <code>options</code> function which is responsible for treating the async operation as a synchronous operation and immediately yields a response.</p>
<p>This function also takes some parameters such as:</p>
<ul>
<li><strong><code>optimisticData</code></strong>: which is the new data you want to display immediately.</li>
<li><strong><code>rollbackOnError</code></strong>: which sets the state to the previous one if the request fails.</li>
<li><strong><code>populateCache</code></strong>: which immediately sets this optimistic data in our UI state.</li>
<li><strong><code>revalidate</code></strong>: which lets us enable or disable another fetch after this function runs.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addTaskOptions = <span class="hljs-function">(<span class="hljs-params">newTask, tasks</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">optimisticData</span>: [...tasks, newTask].sort(
      <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(b.createdAt) - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(a.createdAt)
    ),
    <span class="hljs-attr">rollbackOnError</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">populateCache</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">revalidate</span>: <span class="hljs-literal">false</span>,
  };
};
</code></pre>
<p>To use this optimistic UI method with a <code>create</code> operation, import both functions into your <code>TaskForm</code>. Both functions need to be wrapped in the <code>mutate</code> function since they’re both attempting to mutate the data.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> {
  addTaskMutation <span class="hljs-keyword">as</span> addSingleTask,
  addTaskOptions,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"./services/swrAPI"</span>;

<span class="hljs-keyword">import</span> toast <span class="hljs-keyword">from</span> <span class="hljs-string">"react-hot-toast"</span>;
<span class="hljs-keyword">import</span> { useState } <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">Taskform</span>(<span class="hljs-params">{ mutate, tasks }</span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [description, setDescription] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [assignedTo, setAssignedTo] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> addTaskMutation = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();
    <span class="hljs-keyword">const</span> createdAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString();
    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">await</span> mutate(
        addSingleTask(
          {
            title,
            description,
            assignedTo,
            <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>,
            createdAt,
          },
          tasks
        ),
        addTaskOptions(
          {
            title,
            description,
            assignedTo,
            <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>,
            createdAt,
          },
          tasks
        )
      ); 
     toast.success(<span class="hljs-string">"Task added succesfully."</span>);

    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to add the new task."</span>);
    }
  };
</code></pre>
<p><strong>Note</strong>: The tasks array is passed into the <code>TaskForm</code> via props for this functionality to work.</p>
<p>To see instances where there might be an error, give your functions a 50/50 chance of success or failure, by adding a random condition.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addSingleTask = <span class="hljs-keyword">async</span> ({
  title,
  description,
  completed,
  assignedTo,
  createdAt,
}) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Math</span>.random() &lt; <span class="hljs-number">0.5</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to add new task"</span>);
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> tasksApi.post(tasksUrlEndpoint, {
    title,
    description,
    completed,
    assignedTo,
    createdAt,
  });
  <span class="hljs-keyword">return</span> response.data;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateSingleTask = <span class="hljs-keyword">async</span> (task) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Math</span>.random() &lt; <span class="hljs-number">0.5</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to update task"</span>);
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> tasksApi.patch(<span class="hljs-string">`<span class="hljs-subst">${tasksUrlEndpoint}</span>/<span class="hljs-subst">${task.id}</span>`</span>, task);
  <span class="hljs-keyword">return</span> response.data;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> deleteSingleTask = <span class="hljs-keyword">async</span> ({ id }) =&gt; {
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Math</span>.random() &lt; <span class="hljs-number">0.5</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to update task"</span>);
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> tasksApi.delete(<span class="hljs-string">`<span class="hljs-subst">${tasksUrlEndpoint}</span>/<span class="hljs-subst">${id}</span>`</span>, id);
};
</code></pre>
<p>Testing your <code>create</code> endpoint now gives the following result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/6-Optimistic-UI-with-Create-operation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Optimistic UI with Create operation</em></p>
<p>And voilà! Your app is officially optimistic. It attempts to immediately add the new task to the list even if it fails and gracefully rolls back in the case of an error.</p>
<p>This works similarly for the update operation – starting with the updated <code>update</code> function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateTaskMutation = <span class="hljs-keyword">async</span> (updatedTask, tasks) =&gt; {
  <span class="hljs-keyword">const</span> updatedTaskResponse = <span class="hljs-keyword">await</span> updateSingleTask(updatedTask);
  <span class="hljs-keyword">return</span> tasks.map(<span class="hljs-function">(<span class="hljs-params">task</span>) =&gt;</span>
    task.id === updatedTask.id ? updatedTaskResponse : task
  );
};
</code></pre>
<p>Then its corresponding <code>options</code> function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateTaskOptions = <span class="hljs-function">(<span class="hljs-params">updatedTask, tasks</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">optimisticData</span>: tasks.map(<span class="hljs-function">(<span class="hljs-params">task</span>) =&gt;</span>
      task.id === updatedTask.id ? updatedTask : task
    ),
    <span class="hljs-attr">rollbackOnError</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">populateCache</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">revalidate</span>: <span class="hljs-literal">false</span>,
  };
};
</code></pre>
<p>To test this out, import the new <code>updateSingleTask</code> and <code>updateOptions</code> function in your <code>TaskConatiner</code>, and update the handler function.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> updateTaskMutation = <span class="hljs-keyword">async</span> (updatedTask) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> mutate(
        updateSingleTask(updatedTask, tasks),
        updateTaskOptions(updatedTask, tasks)
      );
      toast.success(<span class="hljs-string">"Successfully updated task"</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to update the task."</span>);
    }
  };
</code></pre>
<p>Which gives the following result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/7-Optimistic-UI-with-Update-operation---fix-gif.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Optimistic UI with Update operation</em></p>
<p>And finally for the delete action:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Function for deleting a task</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> deleteTaskMutation = <span class="hljs-keyword">async</span> (taskToDelete, tasks) =&gt; {
  <span class="hljs-keyword">await</span> deleteSingleTask(taskToDelete);
  <span class="hljs-keyword">return</span> tasks.filter(<span class="hljs-function">(<span class="hljs-params">task</span>) =&gt;</span> task.id !== taskToDelete.id);
};

<span class="hljs-comment">// Options for deleting a task</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> deleteTaskOptions = <span class="hljs-function">(<span class="hljs-params">taskToDelete, tasks</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">optimisticData</span>: tasks.filter(<span class="hljs-function">(<span class="hljs-params">task</span>) =&gt;</span> task.id !== taskToDelete.id),
    <span class="hljs-attr">rollbackOnError</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">populateCache</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">revalidate</span>: <span class="hljs-literal">false</span>,
  };
};
</code></pre>
<p>Which can be used in the <code>TaskContainer</code> delete handler like so:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> deleteTaskMutation = <span class="hljs-keyword">async</span> ({ id }) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> mutate(
        deleteSingleTask({ id }, tasks),
        deleteTaskOptions({ id }, tasks)
      );
      toast.success(<span class="hljs-string">"Successfully deleted task"</span>);
    } <span class="hljs-keyword">catch</span> (err) {
      toast.error(<span class="hljs-string">"Failed to delete the task."</span>);
    }
  };
</code></pre>
<p>Which gives this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/8-Optimistic-UI-with-Delete-operation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Optimistic UI with Delete operation</em></p>
<h2 id="heading-drawbacks-of-optimistic-ui">Drawbacks of Optimistic UI</h2>
<p>Now you must be thinking, if optimistic UI is so great, why not use it everywhere?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/lighter-hairspray.gif" alt="Image" width="600" height="400" loading="lazy">
<em>lighter hairspray gif</em></p>
<p>Well, like everything, that action turns chaotic without moderation. Here are some reasons why you should use optimistic UI in moderation.</p>
<ol>
<li><strong>Excessive Updates</strong>: Optimistic UI might get a bit carried away with updates, especially if your app's moving faster than your internet connection. Too many updates can slow things down, so it's essential to strike a balance.</li>
<li><strong>Exposing server-side logic</strong>: While offloading all the smarts to your app (like generating unique IDs or checking if that username is already taken) is tempting, remember that your server plays a crucial role too. Letting the front end of your app handle everything can lead to security risks and messy code, so be mindful of where you're putting your logic.</li>
<li><strong>Managing Mishaps:</strong> While Optimistic UI typically expects smooth sailing, life has a way of throwing curveballs. From a sudden internet hiccup to the server taking an unexpected coffee break, glitches can be quite a headache to manage gracefully.</li>
<li><strong>Avoid Rapid Changes</strong>: Imagine adding an item to your shopping cart, and then deciding to remove it before the "add" request even reaches the server. It's like changing your mind at the checkout counter – a bit confusing, right? Rapid changes like these can leave your app disoriented, so it's best to proceed cautiously.</li>
</ol>
<h2 id="heading-ideal-use-cases-for-optimistic-ui">Ideal Use Cases for Optimistic UI</h2>
<p>While optimistic UI may not be the holy grail of state management you were hoping to discover, it does have some good use cases such as:</p>
<ol>
<li><strong>Instant Messaging Apps</strong>: Almost all instant messaging platforms currently use this pattern. Your messages appear instantly in the chat window, even before they're confirmed by the server. This creates a seamless and responsive chatting experience, keeping the conversation flowing effortlessly.</li>
<li><strong>Collaborative Editing Tools</strong>: Whether you're working on a document with colleagues or collaborating on a project with teammates, Optimistic UI ensures that changes are reflected in real time. As you type, edit, or make updates, your changes are immediately visible to others, fostering collaboration and productivity.</li>
<li><strong>Social Media Feeds</strong>: Scroll through your social media feed, and you'll see posts, likes, and comments popping up like magic. Optimistic UI ensures that interactions, such as liking a post or leaving a comment, are reflected instantly, providing a more engaging browsing experience.</li>
<li><strong>E-commerce Websites</strong>: Adding items to your shopping cart, updating quantities, and checking out should feel like a breeze. Optimistic UI speeds up the shopping process by immediately updating your cart and displaying feedback, such as item availability or pricing changes, without delay.</li>
</ol>
<p>For convenience, here are some resources you may need:</p>
<ul>
<li><a target="_blank" href="https://github.com/Daiveedjay/Optimistic-UI-with-SWR/tree/starter">Starter Code</a></li>
<li><a target="_blank" href="https://github.com/Daiveedjay/Optimistic-UI-with-SWR/tree/final">Finished Code</a></li>
</ul>
<p>I'd like to acknowledge <a target="_blank" href="https://x.com/yesdavidgray?t=DlFXltzVgL_iokc_225Fgw&amp;s=08">Dave Gray</a>. It was <a target="_blank" href="https://www.youtube.com/watch?v=6gb6oyO1Tyg">his YouTube video</a> that inspired this article. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As we wrap up our dive into Optimistic UI, it's clear that this technique can be a user experience game-changer. It's the rush of your message popping up instantly or your shopping cart updating in real-time.</p>
<p>Optimistic UI is about speed as well as how it makes users feel – connected, empowered, and delighted. So, next time you click and see the magic unfold, remember: it's not just code...it's the pulse of user happiness (not a Coca-Cola ad 😂). Keep that magic alive in your apps!</p>
<p>Happy coding, and have an optimistic day!</p>
<p><strong>Like my articles?</strong></p>
<p>Feel free to <a target="_blank" href="https://www.buymeacoffee.com/JajaDavid">buy me a coffee here</a>, to keep my brain chugging and provide more articles like this.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/coffee-tom.gif" alt="coffee-tom" width="600" height="400" loading="lazy">
<em>Coffee Tom</em></p>
<h3 id="heading-contact-information"><strong>Contact Information</strong></h3>
<p>Want to connect or contact me? Feel free to hit me up on the following:</p>
<ul>
<li>Twitter / X: <a target="_blank" href="https://twitter.com/JajaDavid8">@jajadavid8</a></li>
<li>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/david-jaja-8084251b4/">David Jaja</a></li>
<li>Email: Jajadavidjid@gmail.com</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Shadcn with Next.js 14 ]]>
                </title>
                <description>
                    <![CDATA[ Shadcn is a collection of beautifully designed, accessible, and customizable React components that you can use to build modern web applications with Next.js. With Shadcn, you can quickly and easily create user interfaces that are both stylish and fun... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/shadcn-with-next-js-14/</link>
                <guid isPermaLink="false">66bb882d6b3bd8d6bf25ae2f</guid>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sahil ]]>
                </dc:creator>
                <pubDate>Thu, 01 Feb 2024 15:21:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Neon-Green-Bold-Quote-Motivational-Tweet-Instagram-Post-3-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Shadcn is a collection of beautifully designed, accessible, and customizable React components that you can use to build modern web applications with Next.js. With Shadcn, you can quickly and easily create user interfaces that are both stylish and functional.</p>
<p>If you are looking for a way to build modern, stylish, and accessible web applications with Next.js, then Shadcn is a great option.</p>
<p>In this guide, you'll learn how to install and use Shadcn in your Next.js projects, how to style elements, and how to customize Shadcn components.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-shadcn">What is Shadcn?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-nextjs-and-shadcn">How to Install Next.js and Shadcn</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-nextjs">How to Install Next.js</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-shadcn">How to Install Shadcn</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-shadcn-in-nextjs">How to Use Shadcn in Next.js</a></li>
<li><a class="post-section-overview" href="#heading-how-to-style-a-button-the-hard-way-and-the-shadcn-way">How to Style a Button The Hard Way and The Shadcn Way</a></li>
<li><a class="post-section-overview" href="#heading-how-to-add-a-component-from-shadcn">How to Add a Component from Shadcn</a></li>
<li><a class="post-section-overview" href="#heading-styling-a-button-the-hard-way-using-tailwind">Styling a Button The Hard Way</a></li>
<li><a class="post-section-overview" href="#heading-styling-a-button-the-shadcn-way">Styling a Button The Shadcn Way</a></li>
<li><a class="post-section-overview" href="#heading-how-to-customize-shadcn-components">How to Customize Shadcn Components</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-what-is-shadcn">What is Shadcn?</h2>
<p>Shadcn UI is not specifically a component library or UI framework. As stated in the documentation, it is described as "a compilation of reusable components that can be easily copied and pasted into our applications."</p>
<p>Shadcn leverages Tailwind CSS and Radix UI as its foundation. It presently offers compatibility with Next.js, Gatsby, Remix, Astro, Laravel, and Vite. There's a <a target="_blank" href="https://ui.shadcn.com/docs/installation/manual">manual integration guide</a> that can help you incorporate it with other technologies.</p>
<p>You can get the complete source code for this tutorial <a target="_blank" href="https://github.com/dotslashbit/fcc-article-resources/tree/main/nextjs-shadcn/my-app">here</a>.</p>
<h2 id="heading-how-to-install-nextjs-and-shadcn">How to Install Next.js and Shadcn</h2>
<p>I'll follow the instructions in the <a target="_blank" href="https://ui.shadcn.com/docs/installation">Shadcn docs</a>, so you can follow along if you like.</p>
<p>First, you have to choose what framework you are currently using. This article and the code in my repo above was written with Next.js in mind, so select the Next.js option.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-30-at-5.23.21-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose a framework to set up Shadcn</em></p>
<p>Now, you need to install and configure a new Next.js project.</p>
<h3 id="heading-how-to-install-nextjs">How to Install Next.js</h3>
<p>I typically use npm, but if you use a different package manager, feel free to copy a command for your respective package manager below.</p>
<p>To install Next.js with npm:</p>
<pre><code class="lang-bash">npx create-next-app@latest my-app --typescript --tailwind --eslint
</code></pre>
<p>To install Next.js with yarn:</p>
<pre><code class="lang-bash">yarn create next-app@latest my-app --typescript --tailwind --eslint
</code></pre>
<p>To install Next.js with pnpm:</p>
<pre><code class="lang-bash">pnpm create next-app@latest my-app --typescript --tailwind --eslint
</code></pre>
<p>To install Next.js with bun:</p>
<pre><code class="lang-bash">bunx --bun create-next-app@latest my-app --typescript --tailwind --eslint
</code></pre>
<p>After running one of those commands, you'll see the following configuration questions:</p>
<pre><code class="lang-bash">Need to install the following packages:
create-next-app@14.1.0
Ok to proceed? (y) y
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import <span class="hljs-built_in">alias</span> (@/*)? … No / Yes
</code></pre>
<p>I selected "No" for the first question as I don't want to have a <code>src</code> directory inside my <code>app</code> directory.</p>
<p>I selected "Yes" for the second question because I want to use app router, which is the recommended way to go for Next.js 14.</p>
<p>Finally, I selected "No" for the third question because I like the way import works with <code>@</code> in Next.js 14.</p>
<h3 id="heading-how-to-install-shadcn">How to Install Shadcn</h3>
<p>Before continuing, remember to go into the <code>my-app</code> directory in your terminal:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> my-app
</code></pre>
<p>To initialize Shadcn with npm:</p>
<pre><code class="lang-bash">npx shadcn-ui@latest init
</code></pre>
<p>To initialize Shadcn with yarn:</p>
<pre><code class="lang-bash">npx shadcn-ui@latest init
</code></pre>
<p>To initialize Shadcn with pnpm:</p>
<pre><code class="lang-bash">pnpm dlx shadcn-ui@latest init
</code></pre>
<p>To initialize Shadcn with bun:</p>
<pre><code class="lang-bash">bunx --bun shadcn-ui@latest init
</code></pre>
<p>After running one of those commands you'll see some configuration questions again, but this time they're for Shadcn:</p>
<pre><code class="lang-bash">✔ Which style would you like to use? › New York
✔ Which color would you like to use as base color? › Slate
✔ Would you like to use CSS variables <span class="hljs-keyword">for</span> colors? › yes
</code></pre>
<p>You can see the questions and my responses in the code above.</p>
<p>For the first question, there are two options, <code>default</code> and <code>New York</code>. I chose the "New York" style.</p>
<p>For the second question, there are five options <code>Slate</code>, <code>Gray</code>, <code>Zinc</code>, <code>Neutral</code>, <code>Stone</code>. I chose <code>Slate</code> because I like a minimalist black and white styling.</p>
<p>For the third question, I there are two options <code>Yes</code> and <code>No</code>. I chose yes, as I prefer to have CSS variables enabled for styling (although we won't be using this in this article).</p>
<p>You can read more about the <code>style</code> options, <code>base</code> options, and this configuration setup <a target="_blank" href="https://ui.shadcn.com/docs/components-json">here</a>.</p>
<p>And with that, you've set up a new Next.js 14 project with Shadcn.</p>
<p>Now you can see two new directories that have been added to your project directory, <code>components</code> and <code>lib</code>.</p>
<p>Notice that the <code>components</code> directory is currently empty, which means that Shadcn doesn't load up your project with any components you might not use. This gives you a lot of flexibility and keeps your project lightweight (so you can just add the components you need).</p>
<h2 id="heading-how-to-use-shadcn-in-nextjs">How to Use Shadcn in Next.js</h2>
<p>First, let's remove all the boilerplate code from the <code>my-app</code> project's <code>page.tsx</code> file. (You only need to remove the boilerplate code from <code>my-app/page.tsx</code>.)</p>
<p>After removing all the boilerplate code from the <code>page.tsx</code> file inside the <code>app</code> directory, I'll add a simple hello world text.</p>
<p>Here's the updated <code>page.tsx</code> code:</p>
<pre><code class="lang-typescript"><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">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;h1&gt;Hello World&lt;/h1&gt;
    &lt;/&gt;
  );
}
</code></pre>
<p>And here's what your project should look like in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-30-at-5.49.27-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Hello World setup for the Next.js project</em></p>
<h3 id="heading-how-to-style-a-button-the-hard-way-and-the-shadcn-way">How to Style a Button the Hard Way and the Shadcn Way</h3>
<p>Now, lets add two buttons to the page. One button will be simple with no styling, and the other will be a component from Shadcn.</p>
<h4 id="heading-how-to-add-a-component-from-shadcn">How To Add a Component from Shadcn</h4>
<p>Before we add our buttons, though, we have to learn how to add a component from Shadcn into our project. Here's how to do that:</p>
<ol>
<li>Go to the <a target="_blank" href="https://ui.shadcn.com/docs">Shadcn docs</a>.</li>
<li>Click on whatever component you want to use.</li>
<li>Then you'll see the command you should run to add that component to your project.</li>
<li>Finally, import that component into your project and start using it.</li>
</ol>
<p>To add the <code>Button</code> component from Shadcn, follow these steps:</p>
<ol>
<li>Go to the <a target="_blank" href="https://ui.shadcn.com/docs/components/button">Button component page</a>.</li>
<li>Then run this command in your terminal: <code>npx shadcn-ui@latest add button</code>. Note: This command is for npm – if you use a different package manager, you'll need to modify the command slightly.</li>
<li>Finally, import the button component in the file where you want to use it.</li>
</ol>
<p>Now we'll see examples of adding a button in two different ways: using Tailwind CSS, and using Shadcn.</p>
<h3 id="heading-styling-a-button-the-hard-way-using-tailwind">Styling a Button the Hard Way (Using Tailwind)</h3>
<pre><code class="lang-typescript"><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">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;button className=<span class="hljs-string">"p-2 bg-orange-400"</span>&gt;Click me&lt;/button&gt;
    &lt;/&gt;
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-31-at-9.11.58-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Custom button with orange background</em></p>
<p>I have created a button with an orange background having a padding of 2 units. You can see that it looks ugly and also doesn't have any hover effects by default.</p>
<h3 id="heading-styling-a-button-the-shadcn-way">Styling a Button the Shadcn Way</h3>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/ui/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">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;Button variant=<span class="hljs-string">"outline"</span>&gt;Button&lt;/Button&gt;
    &lt;/&gt;
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-31-at-9.16.22-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Shadcn default button</em></p>
<p>To use the Shadcn button, first import the <code>Button</code> component to the file where you want to use it – you don't need to add any styling to it (You can customize it, which you'll learn how to do in the next section). By default it looks good and it has hover effects. So just import the component and then you can use it.</p>
<p>You can also play around with the different options that Shadcn components give you. Either go to the docs page of that component and take a look at the options or open up the component's source code that is inside the <code>components/ui</code> directory.</p>
<p>Let's take a look at <code>button.tsx</code> source code to check how many variants of buttons you can create.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Slot } <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-slot"</span>;
<span class="hljs-keyword">import</span> { cva, <span class="hljs-keyword">type</span> VariantProps } <span class="hljs-keyword">from</span> <span class="hljs-string">"class-variance-authority"</span>;

<span class="hljs-keyword">import</span> { cn } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/utils"</span>;

<span class="hljs-keyword">const</span> buttonVariants = cva(
  <span class="hljs-string">"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"</span>,
  {
    variants: {
      variant: {
        <span class="hljs-keyword">default</span>:
          <span class="hljs-string">"bg-primary text-primary-foreground shadow hover:bg-primary/90"</span>,
        destructive:
          <span class="hljs-string">"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"</span>,
        outline:
          <span class="hljs-string">"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"</span>,
        secondary:
          <span class="hljs-string">"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"</span>,
        ghost: <span class="hljs-string">"hover:bg-accent hover:text-accent-foreground"</span>,
        link: <span class="hljs-string">"text-primary underline-offset-4 hover:underline"</span>,
      },
      size: {
        <span class="hljs-keyword">default</span>: <span class="hljs-string">"h-9 px-4 py-2"</span>,
        sm: <span class="hljs-string">"h-8 rounded-md px-3 text-xs"</span>,
        lg: <span class="hljs-string">"h-10 rounded-md px-8"</span>,
        icon: <span class="hljs-string">"h-9 w-9"</span>,
      },
    },
    defaultVariants: {
      variant: <span class="hljs-string">"default"</span>,
      size: <span class="hljs-string">"default"</span>,
    },
  }
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ButtonProps
  <span class="hljs-keyword">extends</span> React.ButtonHTMLAttributes&lt;HTMLButtonElement&gt;,
    VariantProps&lt;typeof buttonVariants&gt; {
  asChild?: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-keyword">const</span> Button = React.forwardRef&lt;HTMLButtonElement, ButtonProps&gt;(
  <span class="hljs-function">(<span class="hljs-params">{ className, variant, size, asChild = <span class="hljs-literal">false</span>, ...props }, ref</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> Comp = asChild ? Slot : <span class="hljs-string">"button"</span>;
    <span class="hljs-keyword">return</span> (
      &lt;Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      /&gt;
    );
  }
);
Button.displayName = <span class="hljs-string">"Button"</span>;

<span class="hljs-keyword">export</span> { Button, buttonVariants };
</code></pre>
<p>You can see that there's a <code>variants</code> object, and inside that there are multiple variants to choose from. Notice that there's a <code>size</code> object that allows you to choose different sizes for the button as well.</p>
<p>You can also see that there's a <code>defaultVariants</code> object that stores the default variant and the default size of the button.</p>
<h2 id="heading-how-to-customize-shadcn-components">How to Customize Shadcn Components</h2>
<p>Remember that after installing Shadcn, the <code>components</code> directory was empty. But after adding the <code>Button</code> component, you can see that there's a <code>ui</code> directory inside <code>components</code> directory. And inside the <code>ui</code> directory you'll have the <code>Button.tsx</code> file, which is the code for the <code>Button</code> component.</p>
<p>If you open the <code>Button.tsx</code> file, you'll see that there are multiple variants of the <code>Button</code> component like <code>default</code>, <code>destructive</code>, <code>outline</code>, <code>secondary</code>, <code>ghost</code>, and <code>link</code>. There's also a default size, and other sizes to choose from:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>
<span class="hljs-keyword">import</span> { Slot } <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-slot"</span>
<span class="hljs-keyword">import</span> { cva, <span class="hljs-keyword">type</span> VariantProps } <span class="hljs-keyword">from</span> <span class="hljs-string">"class-variance-authority"</span>

<span class="hljs-keyword">import</span> { cn } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/utils"</span>

<span class="hljs-keyword">const</span> buttonVariants = cva(
  <span class="hljs-string">"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"</span>,
  {
    variants: {
      variant: {
        <span class="hljs-keyword">default</span>:
          <span class="hljs-string">"bg-primary text-primary-foreground shadow hover:bg-primary/90"</span>,
        destructive:
          <span class="hljs-string">"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"</span>,
        outline:
          <span class="hljs-string">"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"</span>,
        secondary:
          <span class="hljs-string">"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"</span>,
        ghost: <span class="hljs-string">"hover:bg-accent hover:text-accent-foreground"</span>,
        link: <span class="hljs-string">"text-primary underline-offset-4 hover:underline"</span>,
      },
      size: {
        <span class="hljs-keyword">default</span>: <span class="hljs-string">"h-9 px-4 py-2"</span>,
        sm: <span class="hljs-string">"h-8 rounded-md px-3 text-xs"</span>,
        lg: <span class="hljs-string">"h-10 rounded-md px-8"</span>,
        icon: <span class="hljs-string">"h-9 w-9"</span>,
      },
    },
    defaultVariants: {
      variant: <span class="hljs-string">"default"</span>,
      size: <span class="hljs-string">"default"</span>,
    },
  }
)

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ButtonProps
  <span class="hljs-keyword">extends</span> React.ButtonHTMLAttributes&lt;HTMLButtonElement&gt;,
    VariantProps&lt;typeof buttonVariants&gt; {
  asChild?: <span class="hljs-built_in">boolean</span>
}

<span class="hljs-keyword">const</span> Button = React.forwardRef&lt;HTMLButtonElement, ButtonProps&gt;(
  <span class="hljs-function">(<span class="hljs-params">{ className, variant, size, asChild = <span class="hljs-literal">false</span>, ...props }, ref</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> Comp = asChild ? Slot : <span class="hljs-string">"button"</span>
    <span class="hljs-keyword">return</span> (
      &lt;Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      /&gt;
    )
  }
)
Button.displayName = <span class="hljs-string">"Button"</span>

<span class="hljs-keyword">export</span> { Button, buttonVariants }
</code></pre>
<p>One of the best parts about Shadcn components is that you can customize them and remove variants that you won't use. You can also add your own variants to the component.</p>
<p>For example, say that you want to add the custom button we coded first as a Shadcn <code>Button</code> component variant. You can do that like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Slot } <span class="hljs-keyword">from</span> <span class="hljs-string">"@radix-ui/react-slot"</span>;
<span class="hljs-keyword">import</span> { cva, <span class="hljs-keyword">type</span> VariantProps } <span class="hljs-keyword">from</span> <span class="hljs-string">"class-variance-authority"</span>;

<span class="hljs-keyword">import</span> { cn } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/utils"</span>;

<span class="hljs-keyword">const</span> buttonVariants = cva(
  <span class="hljs-string">"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"</span>,
  {
    variants: {
      variant: {
        <span class="hljs-keyword">default</span>:
          <span class="hljs-string">"bg-primary text-primary-foreground shadow hover:bg-primary/90"</span>,
        destructive:
          <span class="hljs-string">"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"</span>,
        outline:
          <span class="hljs-string">"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"</span>,
        secondary:
          <span class="hljs-string">"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"</span>,
        ghost: <span class="hljs-string">"hover:bg-accent hover:text-accent-foreground"</span>,
        link: <span class="hljs-string">"text-primary underline-offset-4 hover:underline"</span>,
        myButton: <span class="hljs-string">"p-2 bg-orange-400"</span>,
      },
      size: {
        <span class="hljs-keyword">default</span>: <span class="hljs-string">"h-9 px-4 py-2"</span>,
        sm: <span class="hljs-string">"h-8 rounded-md px-3 text-xs"</span>,
        lg: <span class="hljs-string">"h-10 rounded-md px-8"</span>,
        icon: <span class="hljs-string">"h-9 w-9"</span>,
      },
    },
    defaultVariants: {
      variant: <span class="hljs-string">"default"</span>,
      size: <span class="hljs-string">"default"</span>,
    },
  }
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ButtonProps
  <span class="hljs-keyword">extends</span> React.ButtonHTMLAttributes&lt;HTMLButtonElement&gt;,
    VariantProps&lt;typeof buttonVariants&gt; {
  asChild?: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-keyword">const</span> Button = React.forwardRef&lt;HTMLButtonElement, ButtonProps&gt;(
  <span class="hljs-function">(<span class="hljs-params">{ className, variant, size, asChild = <span class="hljs-literal">false</span>, ...props }, ref</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> Comp = asChild ? Slot : <span class="hljs-string">"button"</span>;
    <span class="hljs-keyword">return</span> (
      &lt;Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      /&gt;
    );
  }
);
Button.displayName = <span class="hljs-string">"Button"</span>;

<span class="hljs-keyword">export</span> { Button, buttonVariants };
</code></pre>
<p>Notice, I have added a new variant <code>myButton</code> and then simply pasted the styling that we used for the custom button. That's it and now you have your own custom button inside the Shadcn <code>Button</code> component.</p>
<p>Notice that the code now includes a new variant named <code>myButton</code>, and I simply pasted in the styling for the custom button from our ealier example. And that's it! Now you have your own custom Shadcn <code>Button</code> component variant.</p>
<p>Here's how you can use the custom <code>myButton</code> variant in your project:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/ui/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">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"flex justify-center items-center flex-col gap-10"</span>&gt;
      &lt;Button variant=<span class="hljs-string">"outline"</span> size=<span class="hljs-string">"sm"</span>&gt;
        sm button
      &lt;/Button&gt;
      &lt;Button variant=<span class="hljs-string">"destructive"</span> size=<span class="hljs-string">"lg"</span>&gt;
        large button
      &lt;/Button&gt;
      &lt;Button variant=<span class="hljs-string">"ghost"</span> size=<span class="hljs-string">"lg"</span>&gt;
        ghost button
      &lt;/Button&gt;
      &lt;Button variant=<span class="hljs-string">"link"</span> size=<span class="hljs-string">"lg"</span>&gt;
        link button
      &lt;/Button&gt;
      &lt;Button variant=<span class="hljs-string">"myButton"</span>&gt;My Button&lt;/Button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-31-at-9.33.59-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Shadcn multiple variants buttons</em></p>
<p>Note that I've added more variants of the <code>Button</code> component, just to show you that you can create multiple types of buttons with different sizes very easily.</p>
<p>The last button in the example above has the variant <code>myButton</code>, which is the custom variant you added to the <code>Button.tsx</code> file. But that just affects the styling, and you can add your own custom size if you'd like.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this guide you learned how to integrate Shadcn in your Next.js projects. You can dive further into Shadcn's extensive component library and use them as-is, or you can customize them to your heart's content. The power to create your next app awaits – go build it!</p>
<p>If you have any feedback on this article, then please DM me on <a target="_blank" href="https://twitter.com/introvertedbot">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Pick a Font – An In-Depth Guide for Developers ]]>
                </title>
                <description>
                    <![CDATA[ Fonts are not always free. If you're fetching a font that isn't already on your user's phone or computer, they'll have to download it. And this will impact performance. In documents and subtitles, emb ]]>
                </description>
                <link>https://www.freecodecamp.org/news/things-to-consider-when-picking-fonts/</link>
                <guid isPermaLink="false">66d460f88812486a37369d5c</guid>
                
                    <category>
                        <![CDATA[ fonts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Seth Falco ]]>
                </dc:creator>
                <pubDate>Wed, 13 Sep 2023 11:18:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/12ee3390-c16b-4467-8437-67706712a2e5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Fonts are not always free. If you're fetching a font that isn't already on your user's phone or computer, they'll have to download it. And this will impact performance.</p>
<p>In documents and subtitles, embedding fonts can easily increase the file size tenfold. As for the web, here are some popular fonts and a potential network impact:</p>
<table>
<thead>
<tr>
<th>Font</th>
<th>Size</th>
<th>Wi-Fi</th>
<th>Regular 4G/LTE</th>
<th>Regular 3G</th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://fonts.bunny.net/family/roboto">Roboto</a></td>
<td>160 KB</td>
<td>0.04 s</td>
<td>0.34 s</td>
<td>1.81 s</td>
</tr>
<tr>
<td><a href="https://fonts.bunny.net/family/montserrat">Montserrat</a></td>
<td>217 KB</td>
<td>0.06 s</td>
<td>0.45 s</td>
<td>2.41 s</td>
</tr>
<tr>
<td><a href="https://fonts.bunny.net/family/inter">Inter</a></td>
<td>253 KB</td>
<td>0.07 s</td>
<td>0.53 s</td>
<td>2.80 s</td>
</tr>
<tr>
<td><a href="https://fonts.bunny.net/family/noto-sans">Noto Sans</a></td>
<td>292 KB</td>
<td>0.08 s</td>
<td>0.60 s</td>
<td>3.21 s</td>
</tr>
<tr>
<td><a href="https://fonts.bunny.net/family/jetbrains-mono">JetBrains Mono</a></td>
<td>125 KB</td>
<td>0.04 s</td>
<td>0.27 s</td>
<td>1.43 s</td>
</tr>
</tbody></table>
<p><em>Size is based on rendering "Hello, Čihař!" in regular, bold, italic, and bold italic – it varies based on what characters you use. The estimated network speeds and latency are taken from</em> <a href="https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/throttling/index.html"><em>Throttling - Firefox Source Docs</em></a><em>.</em></p>
<p>On the modern web, we've normalized fetching fonts from client-side, or embedding fonts in resources that are served to users. While this may be tempting, it actually makes very little sense for most use-cases.</p>
<p>This isn't suggesting to never use external fonts. Just a reminder that fonts aren't free, and that it's a good idea to review if it's worth packaging or fetching external fonts when it's avoidable.</p>
<p>Instead, I'd recommend you consider an expansive font selection, featuring typefaces available across operating systems. There are times we should fetch external fonts, but it shouldn't be the default attitude in everything that we build.</p>
<p>In short, you may just need an arbitrary typeface to show arbitrary text on your website. That's fine. But it's worth sticking to the wide array of typefaces already installed on the client's operating system.</p>
<p>In other words… only fetch an external font when it actually enhances the user experience!</p>
<h2 id="heading-why">Why?</h2>
<p>Given the number of typefaces available on all operating systems, there are likely many suitable options for your use-case.</p>
<p>There's no need to specifically fetch Roboto, Inter, or another font that's similar enough to the preinstalled options.</p>
<p>This is particularly relevant to corporate websites, blogs, forums, and web applications.</p>
<p>The user is there to consume content or get a task done. Unless you're looking to be creative, the average user doesn't know, and doesn't care, what typeface it has so long as it's legible.</p>
<p>Meanwhile, they may care for other things impacted by your font choices…</p>
<h3 id="heading-performance">Performance</h3>
<p>Whether we're talking about embedding fonts in offline documents, or fetching fonts on the web, it increases the overall size and load time of resources.</p>
<p>Typefaces can be upwards of 160 KB per font face. The impact of this can be significant on slower networks or old mobile devices.</p>
<p>Particularly on the web, you'd derive more value building a lightning-fast user experience, than fetching a typeface the user didn't ask for.</p>
<p>Until the typeface has finished fetching, sites can choose to block rendering or swap, neither of which is ideal.</p>
<p>Font swapping is when the font changes shortly after visiting the site, leading to a flicker and an increase in <a href="https://web.dev/articles/cls">Cumulative Layout Shift</a>.</p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/mdn-font-swap.gif" alt="mdn-font-swap" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>A demo of blocking and font swapping on the MDN website. I refreshed with the cache disabled on a high-spec laptop connected to Wi-Fi with no throttling.</em></p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/out.gif" alt="out" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>A demo of the MDN website using Nimbus Sans, based on Helvetica, instead of external fonts. I refreshed under the same conditions.</em></p>
<p>Dropping external fonts is pretty simple, but can improve load time, reduce bandwidth usage, and avoid font swapping, which all improve your <a href="https://web.dev/articles/vitals">Core Web Vitals</a> and SEO.</p>
<h3 id="heading-privacy">Privacy</h3>
<p>When fetching fonts from a third-party server such as Google Fonts, client information is leaked to the third party. This includes the <a href="https://developer.mozilla.org/en-US/docs/Glossary/IP_Address">IP Address</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent">User-Agent</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referer">Referer</a>, among other headers.</p>
<p>Every website that loads a typeface from Google Fonts has given Google the potential to track the visitor. The domain you visited, the time you accessed it, what browser and operating system you're on, and so on. They can form a timeline of the websites you visit from the fonts alone.</p>
<p>Google states that they don't track or store this information. But given the nature of the internet, they inevitably must receive it.</p>
<p>A German court has actually ruled that websites that load Google Fonts are violating GDPR:</p>
<blockquote>
<p>"A regional court in the German city of Munich has ordered a website operator to pay €100 in damages for transferring a user's personal data — i.e., IP address — to Google via the search giant's Fonts library without the individual's consent." (Source: <a href="https://thehackernews.com/2022/01/german-court-rules-websites-embedding.html">German Court Rules Websites Embedding Google Fonts Violates GDPR</a>)</p>
</blockquote>
<p>This problem can be avoided by self-hosting fonts. If you're going to use an external font, make sure you consider this.</p>
<p>But you should also know that some users <a href="https://support.mozilla.org/en-US/kb/change-fonts-and-colors-websites-use#w_custom-fonts">disable custom fonts</a> or <a href="https://github.com/gorhill/uBlock/wiki/Per-site-switches#no-remote-fonts">block third-party fonts</a>, so you should still specify at least a generic family name regardless.</p>
<blockquote>
<p>"You should always include at least one generic family name in a <code>font-family</code> list, since there's no guarantee that any given font is available. This lets the browser select an acceptable fallback font when necessary.‌‌‌‌‌‌‌‌" (Source: <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-family#try_it">MDN Documentation for font-family</a>)</p>
</blockquote>
<h3 id="heading-familiarity">Familiarity</h3>
<p>Users are familiar with the experience of their operating system.</p>
<p>Maybe not how it works under the hood, or even how to perform simple operations, but they do encounter the welcome screen, context menus, and their preinstalled applications regularly.</p>
<p>It's safer to stick with typefaces the user already has access to because these are the typefaces the user is already accustomed to reading from.</p>
<p>This argument is in a similar vein to why it's a good idea to use the system date picker, color picker, or modal/dialog boxes instead of creating custom ones.</p>
<p>Users are familiar with their system!</p>
<p>From my experience, often one of the following occurs:</p>
<ul>
<li><p>The user couldn't tell that an external font was used, making it largely redundant. Most non-specialists experience this everyday, it's hard to even tell that websites are using different fonts from each other unless you're conscious of it.</p>
</li>
<li><p>The user was able to tell, and thus has a different reading experience than what they're used to. The potential for disruption depends on the needs of the user, but that risk is often unnecessary.</p>
</li>
</ul>
<p>Unless you have a reason to change it, it's best to stick with what the user is familiar with.</p>
<h2 id="heading-who-else-does-this">Who Else Does This?</h2>
<p>Wikipedia is the most notable example, and they even have a page elaborating on the topic: <a href="https://en.wikipedia.org/wiki/Wikipedia:Typography">Meta page on Wikipedia's use of typography</a>.</p>
<p>Some of the most popular sites don't fetch a single font on their landing page, in favor of using system fonts only:</p>
<table>
<thead>
<tr>
<th>Site</th>
<th>Font Stack</th>
</tr>
</thead>
<tbody><tr>
<td>Instagram</td>
<td><code>-apple-system,&nbsp;BlinkMacSystemFont,&nbsp;"Segoe UI",&nbsp;Roboto,&nbsp;Helvetica,&nbsp;Arial,&nbsp;sans-serif</code></td>
</tr>
<tr>
<td>Wikipedia</td>
<td><code>-apple-system,&nbsp;'BlinkMacSystemFont',&nbsp;'Segoe UI',&nbsp;'Roboto',&nbsp;'Inter',&nbsp;'Helvetica',&nbsp;'Arial',&nbsp;sans-serif</code></td>
</tr>
<tr>
<td>Reddit</td>
<td><code>-apple-system,&nbsp;BlinkMacSystemFont,&nbsp;"Segoe UI",&nbsp;Roboto,&nbsp;"Helvetica Neue",&nbsp;Arial,&nbsp;"Apple Color Emoji",&nbsp;"Segoe UI Emoji",&nbsp;"Segoe UI Symbol",&nbsp;sans-serif</code></td>
</tr>
<tr>
<td>Bing</td>
<td><code>"-apple-system",&nbsp;HelveticaNeue,&nbsp;Roboto,&nbsp;Arial,&nbsp;sans-serif</code></td>
</tr>
</tbody></table>
<p>You can verify for yourself by inspecting the site with your browser's development tools.</p>
<p>There are no outgoing network requests for fonts, and the <code>font-family</code> properties are set to system fonts only.</p>
<h2 id="heading-exceptions">Exceptions</h2>
<p>There are times loading and embedding fonts does make sense, particularly if the look and feel you're after is significantly different from common system fonts:</p>
<ul>
<li><p>You're targeting an environment that doesn't have typefaces available.</p>
</li>
<li><p>To fit with existing branding, like an in-house font.</p>
</li>
<li><p>A creative or unique design, especially relevant for gaming and artsy sites.</p>
</li>
<li><p>Icon fonts like <a href="https://openmoji.org">OpenMoji</a>, but note that most clients come with emojis already.</p>
</li>
<li><p>A website that's literally for distributing, displaying, and testing fonts.</p>
</li>
</ul>
<h2 id="heading-consequences">Consequences</h2>
<p>If you apply a local font stack, your text content may not look pixel-for-pixel identical across clients. But you should measure success by the user experience.</p>
<p>It's important for the site to feel familiar, but there are more significant changes between clients already, like the human-interface, resolutions, and DPI.</p>
<p>Compared to this, it's fine if the arch of the <code>a</code> has a slightly different radius, or the tick on the <code>l</code> is a few pixels longer. In fact, this is unlikely to get noticed, so it's unlikely to impact the user experience at all.</p>
<p>Users would sooner have qualms with the difference in speed or a flicker, before the difference between similar typefaces.</p>
<p>Another argument is that allowing different typefaces may make the layout difficult to manage. Glyphs can have different widths, and therefore take up varying space.</p>
<p>But modern sites should be following <a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/CSS_layout/Responsive_Design">responsive design</a>, so you should be taking the time to make the pages fluid anyway.</p>
<p>To minimize impact, you can use <a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Text_styling/Fundamentals#web_safe_fonts">web safe fonts</a>.</p>
<p>If you dislike how limiting that is, pick a typeface included with your operating system, and find similar typefaces on other operating systems.</p>
<p>Even better if you can pick <a href="https://en.wikipedia.org/wiki/Typeface#Font_metrics">metrically compatible typefaces</a>.</p>
<h3 id="heading-comparison">Comparison</h3>
<p>Let's visit a website and see what it's like to disable downloadable fonts.</p>
<p>I'll also replace all font stacks to use Helvetica.</p>
<p>Note, my computer doesn't actually have Helvetica installed, so my operating system automatically translates this to Nimbus Sans, which is based on Helvetica. Nimbus Sans is preinstalled on <a href="https://www.debian.org">Debian</a>.</p>
<p>In the case of MDN, is the second version really so undesirable that we need to load a 252 KB font, given the penalties and demonstrations raised above? Ultimately, this one is down to user preference, so I'll let you decide.</p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/1.png" alt="1" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>MDN, with the Inter typeface fetched from client-side.</em></p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/1-1.png" alt="1-1" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>MDN, with the font-family overridden to use Helvetica.</em></p>
<p>On the flip side, that doesn't mean to never fetch fonts. There are examples where the aesthetic may be more valuable to the user experience than the performance penalty.</p>
<p>Let's look at <a href="https://framasoft.org">Framasoft</a>. They went for a more creative look and feel, also featuring a lot of <a href="https://www.davidrevoy.com">David Revoy's</a> illustrations.</p>
<p>Using Tovari Sans was a design choice which enhances the user experience, and isn't easily replaceable with a local font stack.</p>
<p>If we were to take that font away, the page feels inconsistent and unpolished. Even if we cleaned up the CSS, we'd still be detracting from the theme of the website.</p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/1-2.png" alt="1-2" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>Framasoft, with the Tovari Sans typeface fetched from client-side.</em></p>
<img src="https://www.freecodecamp.org/news/content/images/2023/09/1-4.png" alt="1-4" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>Framasoft, with the font-family overridden to use Helvetica.</em></p>
<h2 id="heading-resources">Resources</h2>
<p>Whether you want to go local, or just need to specify some fallback fonts, here are some helpful resources for picking out your font stack:</p>
<ul>
<li><p><a href="https://developer.apple.com/fonts/system-fonts/">List of typefaces included with Apple operating systems</a></p>
</li>
<li><p><a href="https://learn.microsoft.com/en-us/typography/fonts/windows_11_font_list#introduction">List of typefaces included with Windows</a></p>
</li>
<li><p><a href="https://en.wikipedia.org/wiki/Croscore_fonts">Core typefaces included with ChromeOS</a></p>
</li>
<li><p><a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Text_styling/Fundamentals#web_safe_fonts">Documentation for web safe fonts</a></p>
</li>
</ul>
<h2 id="heading-cross-platform-font-stacks">Cross-Platform Font Stacks</h2>
<p>There are countless articles and resources available online that feature predefined font lists you can use. These are referred to as <em>"font stacks"</em>.</p>
<p>In particular, I'd like to highlight a resource by <a href="https://danklammer.com">Dan Klammer</a>, a designer and web developer who created <a href="https://modernfontstacks.com">Modern Font Stacks</a> (<a href="https://github.com/system-fonts/modern-font-stacks">GitHub repository</a>), a website that helps you pick out native font stacks for your project.</p>
<p>Modern Font Stacks proposes a list of fonts for a variety of styles like Neo-Grotesque (a style of sans-serif) or Monospace Code (a style of monospace) and offers a visualization of how it will look across operating systems. It runs through a description of each stack, the CSS to use it, metadata like the weights available, and which of the fonts you personally have installed.</p>
<p>Some font classifications don't explicitly include a font from every operating system that exists, but remember that the generic font family (<code>sans-serif</code>, <code>serif</code>, <code>monospace</code>, <code>cursive</code>, and so on) at the end will have you covered.</p>
<p>If you like the stack, you can run with it. But don't feel constrained either, you can also use it as a starting point and tweak the font stack to your needs.</p>
<p>I've included images from the GitHub repository (at the time of writing), featuring proposed font stacks for two of the most common styles used on the internet today:</p>
<img src="https://www.freecodecamp.org/news/content/images/2024/05/neo-grotesque.png" alt="neo-grotesque" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>Base font stack proposed by Modern Font Stacks for the Neo-Grotesque style, a type of sans-serif font.</em></p>
<img src="https://www.freecodecamp.org/news/content/images/2024/05/monospace-code.png" alt="monospace-code" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><em>Base font stack proposed by Modern Font Stacks for the Monospace Code style, a type of monospace font.</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In the end, the user experience is what matters most. Sometimes that means prioritizing visual design, other times that means prioritizing performance.</p>
<p>I hope this was worth your time, and that with the knowledge you can make an informed decision when choosing fonts for your next project.</p>
<p>Feedback and questions welcome, you can hit me up on <a href="https://github.com/SethFalco">GitHub</a> or <a href="https://fosstodon.org/@sethi">Mastodon</a>.</p>
<p><em>Cover art illustrated by</em> <a href="https://hashrock.info"><em>hashrock</em></a> <em>and released under</em> <a href="https://creativecommons.org/licenses/by/4.0/"><em>CC BY 4.0</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Un-Styled UI Components – Guide for Front-End Developers ]]>
                </title>
                <description>
                    <![CDATA[ Imagine this situation: you are working on a time-sensitive project, and you need to implement some specific UI components that comply with accessibility best practices.  You may know about some libraries that are full of pre-designed UI elements, ea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/unstyled-ui-components-for-front-end-developers/</link>
                <guid isPermaLink="false">66ba0d5ff602a81788fe2182</guid>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chinenye Anikwenze ]]>
                </dc:creator>
                <pubDate>Tue, 29 Aug 2023 15:56:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/article---unstyled-ui-components-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Imagine this situation: you are working on a time-sensitive project, and you need to implement some specific UI components that comply with accessibility best practices. </p>
<p>You may know about some libraries that are full of pre-designed UI elements, each with their own style. But here's the catch – you might only need a handful of these components. So why make your application bulkier? In reality, a significant portion of the bundled styles might go unused. </p>
<p>Well don't worry – that's where <strong>un-styled</strong> UI components come in.</p>
<h2 id="heading-what-are-un-styled-ui-components">What are Un-styled UI Components?</h2>
<p>Un-styled UI components are accessible UI building blocks without pre-set styles. This grants you unmatched authority over the visual presentation and behavior of these interfaces. </p>
<p>The term "<strong>un-styled</strong>" doesn't signify a lack of design – rather, it refers to a blank slate that lets you infuse your creativity and branding without the limitations that come with traditional UI elements. </p>
<p>This enables you to tailor the components to your application's distinct needs, while also prioritizing aesthetics and accessibility.</p>
<h2 id="heading-benefits-of-un-styled-ui-components">Benefits of Un-styled UI Components</h2>
<p>Let's delve into the key features that set un-styled components apart and explore why they may be a must-have for your upcoming projects.</p>
<h3 id="heading-control-over-visual-appearance-and-functionality">Control Over Visual Appearance and Functionality:</h3>
<p>Conventional UI libraries have preset styles that might not align with your design or aesthetics. </p>
<p>Let's use this scenario, for instance: you're working on an e-commerce platform that needs a product catalog. With unstyled UI components, you can tweak each product card's look, hover effects, and interactions to mirror your brand's identity. </p>
<p>This freedom extends to colors, typography, and layout choices, resulting in a coherent, captivating experience unique to your app.</p>
<h3 id="heading-reduced-overhead-and-enhanced-performance">Reduced Overhead and Enhanced Performance:</h3>
<p>Often, in personal projects, we only require a handful of components from extensive libraries. But incorporating these libraries can introduce unnecessary styles and bulk that slow things down. </p>
<p>Un-styled components tackle this issue by letting you include only what you need. This speeds up your app, making it leaner and more efficient, without unnecessary dependencies.</p>
<h3 id="heading-flexibility-for-customization">Flexibility for Customization</h3>
<p>Un-styled components empower you to craft elements seamlessly tailored to your project's demands. This covers their appearance, movements, and reactions to user interactions. </p>
<p>Whether you're building a simple form or a complex interactive feature, un-styled components give you the freedom to mold every detail to align with your design and purpose, harmonizing with your app's overall style.</p>
<h3 id="heading-accessibility-and-user-friendliness">Accessibility and User-Friendliness</h3>
<p>Crafting accessible interfaces that adhere to <a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/aria/">WAI-ARIA design</a> principles is important for developers. Unstyled UI components, often designed with accessibility in focus, offer enhanced usability for a broader user spectrum. This abstraction eliminates manual implementation.</p>
<h3 id="heading-future-ready-development">Future-Ready Development</h3>
<p>Technology evolves, and so do design trends and user expectations. Un-styled components ensure you're primed for what lies ahead. Integrating them empowers you to adapt your app's look and feel as trends shift, without being constrained by outdated styles.</p>
<h3 id="heading-modular-and-scalable-architecture">Modular and Scalable Architecture</h3>
<p>Un-styled components resemble building blocks that seamlessly fit into your project. This streamlines your code and makes it easier to manage. It also lets you reuse these blocks across different app sections, saving time while preserving consistency as your project expands.</p>
<h2 id="heading-exploring-popular-un-styled-ui-components">Exploring Popular Un-styled UI Components</h2>
<p>To give you more context into how un-styled components work, we'll now compare modal components from five common un-styled UI component libraries. </p>
<p>For most of these components, the Dialog components facilitate the creation of interactive, visually pleasing modal boxes for actions like profile editing, confirming decisions, or displaying extra information without navigating from the main content. </p>
<p>I'll also outline the overall features of these component libraries so you'll be able to integrate them into your future projects.</p>
<p>Let's now dive into a selection of the most notable un-styled UI component libraries and examine their dialog components.</p>
<h3 id="heading-radix-ui">Radix UI</h3>
<p>Radix UI's Dialog component, which you can find in the <code>@radix-ui/react-dialog</code> package, is a versatile tool that helps you build popup windows in your React apps. It allows you to interact with certain areas of your program without leaving the current screen.</p>
<p>You can create many types of popup windows, including those that stop the flow (modal) and those that do not (non-modal). </p>
<p>For designing comprehensive dialogs, you have numerous building pieces including <code>Trigger</code>, <code>Portal</code>, <code>Overlay</code>, <code>Content</code>, <code>Title</code>, <code>Description</code>, and <code>Close</code>. You can style it to match your design. It also adheres to accessibility requirements so that everyone can use it.</p>
<p>When you press the <code>Escape</code> key or click the <code>close</code> button, the dialog closes. For screen reader users, special components such as <code>Title</code> and <code>Description</code> are available.</p>
<p>The documentation is extensive and provides examples for several scenarios and It works well with the React ecosystem.</p>
<h4 id="heading-sample-code-from-radix">Sample code from Radix:</h4>
<p>To get started with Radix, you can run this command on your terminal:</p>
<p><code>npm install @radix-ui/react-popover@latest -E</code>  </p>
<p>To use the dialog component, you can import the components like so:</p>
<pre><code><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> Dialog <span class="hljs-keyword">from</span> <span class="hljs-string">'@radix-ui/react-dialog'</span>;

<span class="hljs-keyword">const</span> DialogComponent = <span class="hljs-function">() =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Root</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Trigger</span> <span class="hljs-attr">asChild</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Open profile<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Trigger</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Portal</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Overlay</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"DialogOverlay"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Content</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"DialogContent"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Title</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"DialogTitle"</span>&gt;</span>Edit profile<span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Description</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"DialogDescription"</span>&gt;</span>
          Make changes to your profile here. Click save when you're done.
        <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Description</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">fieldset</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Label"</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"name"</span>&gt;</span>
            Name
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Input"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">defaultValue</span>=<span class="hljs-string">"Chinenye A"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">fieldset</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">fieldset</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Fieldset"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Label"</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"username"</span>&gt;</span>
            Username
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Input"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">defaultValue</span>=<span class="hljs-string">"@chinenye"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">fieldset</span>&gt;</span>
        <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">display:</span> '<span class="hljs-attr">flex</span>', <span class="hljs-attr">marginTop:</span> <span class="hljs-attr">25</span>, <span class="hljs-attr">justifyContent:</span> '<span class="hljs-attr">flex-end</span>' }}&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Close</span> <span class="hljs-attr">asChild</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button green"</span>&gt;</span>Save changes<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.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">Dialog.Close</span> <span class="hljs-attr">asChild</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"IconButton"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Close"</span>&gt;</span>
         Button
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Close</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Content</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Portal</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Root</span>&gt;</span></span>
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DialogComponent;
</code></pre><p>Here's what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/radix-modal.jpg" alt="The image shows a pop up modal with a form. The modal is a card placed on the center of the screen" width="600" height="400" loading="lazy">
<em>Modal screen of the dialog component from Radix UI</em></p>
<p>To learn more about Radix and its other components, <a target="_blank" href="https://www.radix-ui.com/primitives/docs/components/dialog">you can check out their documentation here.</a></p>
<h3 id="heading-shadcns-ui-component">shadcn's UI Component</h3>
<p>shadcn UI components, which are based on Radix UI and Tailwind CSS, deliver a seamless and integrated user experience. </p>
<p>shadcn is efficient and lightweight because you can install only the components that you require. It supports two kinds of popup windows: </p>
<ol>
<li>Those that require a response before closing <code>Alert Dialog</code>  </li>
<li>Those that don't (which is useful for displaying messages)</li>
</ol>
<p>The shadcn UI component is versatile since you can overlay content on the main screen or another popup. It's simple to use for keyboard and screen reader users as well.</p>
<p>To make your popups more visually appealing, you can apply effects like fading, sliding, or zooming. You can combine this with menus such as Context Menus or Dropdown Menus (also part of the Shadcn components) to increase functionality.</p>
<p>The components for the dialog are divided into sections like <code>DialogTrigger</code>, <code>DialogContent</code>, <code>DialogHeader</code>, among others for simpler implementation.</p>
<h4 id="heading-sample-code-from-shadcn">Sample code from shadcn:</h4>
<p>To get started, you can install the shadcn dialog component by running<br><code>npx shadcn-ui@latest add dialog</code>.  </p>
<p>To use the component on your projects, you can import them like this:</p>
<pre><code><span class="hljs-keyword">import</span> {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/ui/dialog"</span>

&lt;Dialog&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DialogTrigger</span>&gt;</span>Open<span class="hljs-tag">&lt;/<span class="hljs-name">DialogTrigger</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DialogContent</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">DialogHeader</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">DialogTitle</span>&gt;</span>Are you sure absolutely sure?<span class="hljs-tag">&lt;/<span class="hljs-name">DialogTitle</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">DialogDescription</span>&gt;</span>
        This action cannot be undone. This will permanently delete your account
        and remove your data from our servers.
      <span class="hljs-tag">&lt;/<span class="hljs-name">DialogDescription</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">DialogHeader</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">DialogContent</span>&gt;</span></span>
&lt;/Dialog&gt;
</code></pre><p>And here's the result of the above code:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/screencapture-ui-shadcn-docs-components-dialog-2023-08-26-07_47_54.png" alt="This screen shows a modal " width="600" height="400" loading="lazy">
<em>Shadcn dialog display</em></p>
<p><a target="_blank" href="https://ui.shadcn.com/docs/components/dialog">You can read their documentation for other use cases</a>.</p>
<h3 id="heading-headless-ui-library">Headless UI Library:</h3>
<p>Headless UI Library provides a fully managed, flexible approach to constructing modal windows. You can use it in both React and Vue applications. </p>
<p>The library lets you customize popup windows to match the look and feel of your program. It also has built-in accessibility features, making it usable by keyboard and screen reader users.</p>
<p>To fit the appearance of your application, you can style the <code>Dialog</code> and <code>Dialog.Panel</code> components with <code>className</code> or <code>style props</code>. The <code>Dialog.Panel</code> can have an overlay or backdrop that can be animated individually to grab attention. It enables you to use CSS to build scrollable dialogs.</p>
<p>The library provides seamless transitions while opening and dismissing popups, which improves the visual experience.</p>
<h4 id="heading-code-sample-from-headless-ui">Code Sample from Headless UI:</h4>
<p>To get started with this library, you can run this command to install it:<br><code>npm install @headlessui/react</code>.  </p>
<p>You can use the dialog components as depicted below:</p>
<pre><code><span class="hljs-keyword">import</span> { Dialog, Transition } <span class="hljs-keyword">from</span> <span class="hljs-string">'@headlessui/react'</span>
<span class="hljs-keyword">import</span> { Fragment, useState } <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">MyModal</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">true</span>)

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">closeModal</span>(<span class="hljs-params"></span>) </span>{
    setIsOpen(<span class="hljs-literal">false</span>)
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">openModal</span>(<span class="hljs-params"></span>) </span>{
    setIsOpen(<span class="hljs-literal">true</span>)
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"fixed inset-0 flex items-center justify-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{openModal}</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">"rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"</span>
        &gt;</span>
          Open dialog
        <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">Transition</span> <span class="hljs-attr">appear</span> <span class="hljs-attr">show</span>=<span class="hljs-string">{isOpen}</span> <span class="hljs-attr">as</span>=<span class="hljs-string">{Fragment}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Dialog</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"div"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"relative z-10"</span> <span class="hljs-attr">onClose</span>=<span class="hljs-string">{closeModal}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Transition.Child</span>
            <span class="hljs-attr">as</span>=<span class="hljs-string">{Fragment}</span>
            <span class="hljs-attr">enter</span>=<span class="hljs-string">"ease-out duration-300"</span>
            <span class="hljs-attr">enterFrom</span>=<span class="hljs-string">"opacity-0"</span>
            <span class="hljs-attr">enterTo</span>=<span class="hljs-string">"opacity-100"</span>
            <span class="hljs-attr">leave</span>=<span class="hljs-string">"ease-in duration-200"</span>
            <span class="hljs-attr">leaveFrom</span>=<span class="hljs-string">"opacity-100"</span>
            <span class="hljs-attr">leaveTo</span>=<span class="hljs-string">"opacity-0"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"fixed inset-0 bg-black bg-opacity-25"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">Transition.Child</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"fixed inset-0 overflow-y-auto"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-full items-center justify-center p-4 text-center"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">Transition.Child</span>
                <span class="hljs-attr">as</span>=<span class="hljs-string">{Fragment}</span>
                <span class="hljs-attr">enter</span>=<span class="hljs-string">"ease-out duration-300"</span>
                <span class="hljs-attr">enterFrom</span>=<span class="hljs-string">"opacity-0 scale-95"</span>
                <span class="hljs-attr">enterTo</span>=<span class="hljs-string">"opacity-100 scale-100"</span>
                <span class="hljs-attr">leave</span>=<span class="hljs-string">"ease-in duration-200"</span>
                <span class="hljs-attr">leaveFrom</span>=<span class="hljs-string">"opacity-100 scale-100"</span>
                <span class="hljs-attr">leaveTo</span>=<span class="hljs-string">"opacity-0 scale-95"</span>
              &gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Panel</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">Dialog.Title</span>
                    <span class="hljs-attr">as</span>=<span class="hljs-string">"h3"</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"text-lg font-medium leading-6 text-gray-900"</span>
                  &gt;</span>
                    Payment successful
                  <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog.Title</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mt-2"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-gray-500"</span>&gt;</span>
                      Your payment has been successfully submitted. We’ve sent
                      you an email with all of the details of your order.
                    <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">className</span>=<span class="hljs-string">"mt-4"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
                      <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
                      <span class="hljs-attr">className</span>=<span class="hljs-string">"inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"</span>
                      <span class="hljs-attr">onClick</span>=<span class="hljs-string">{closeModal}</span>
                    &gt;</span>
                      Got it, thanks!
                    <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">Dialog.Panel</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">Transition.Child</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">Dialog</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Transition</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  )
}
</code></pre><p>Here's what that looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/screencapture-headlessui-react-dialog-2023-08-27-16_28_15.png" alt="A modal postioned at the center with a blue and purple gradient overlay to show how the headless ui components work" width="600" height="400" loading="lazy">
<em>Sample modal made with Headless UI</em></p>
<p>For more details about this component, <a target="_blank" href="https://headlessui.com/react/dialog">you can check out their documentation</a>.</p>
<h3 id="heading-primereact-ui">PrimeReact UI</h3>
<p>PrimeReact UI has a flexible <code>Dialog</code> component that lets you show content in overlay windows.</p>
<p>The dialog's appearance and disappearance times can be changed. It includes tools like resizing and drag-and-drop as well.</p>
<p>It automatically inserts a scrollbar for easy navigation if the material is too long. Based on various screen widths, you can adjust the dialog's width. The <code>position</code> setting allows you to place the dialog in different screen corners.</p>
<p>It is compatible with screen readers and keyboard navigation because it was created with accessibility in mind. Keyboard keys allow users to traverse the dialog. It complies with integration best practices and works nicely with other libraries.</p>
<h4 id="heading-code-sample-from-primereact-ui">Code sample from PrimeReact UI:</h4>
<p>To get started, run this command on your terminal: </p>
<p><code>npm install primereact</code></p>
<p>Here is a code snippet of the dialog component:</p>
<pre><code><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'primereact/button'</span>;
<span class="hljs-keyword">import</span> { Dialog } <span class="hljs-keyword">from</span> <span class="hljs-string">'primereact/dialog'</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">BasicDemo</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [visible, setVisible] = useState(<span class="hljs-literal">false</span>);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"card flex justify-content-center"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Show"</span> <span class="hljs-attr">icon</span>=<span class="hljs-string">"pi pi-external-link"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setVisible(true)} /&gt;
            <span class="hljs-tag">&lt;<span class="hljs-name">Dialog</span> <span class="hljs-attr">header</span>=<span class="hljs-string">"Header"</span> <span class="hljs-attr">visible</span>=<span class="hljs-string">{visible}</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">width:</span> '<span class="hljs-attr">50vw</span>' }} <span class="hljs-attr">onHide</span>=<span class="hljs-string">{()</span> =&gt;</span> setVisible(false)}&gt;
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"m-0"</span>&gt;</span>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
                    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
                    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
                    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre><p>Here's what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/screencapture-primereact-org-dialog-2023-08-26-08_09_58.png" alt="This dialog component from primereact is positioned at the right of the screen and has a gray overlay" width="600" height="400" loading="lazy">
<em>Position of dialog component on center-right of the screen</em></p>
<p>For more information about the library, <a target="_blank" href="https://primereact.org/dialog/">visit their documentation here</a>.</p>
<h3 id="heading-reach-ui-dialog-component">Reach UI Dialog Component:</h3>
<p>The Reach UI Dialog component is a great option for designing user friendly and accessible popup windows.</p>
<p>It provides accurate control and is simple to use. It functions flawlessly on a variety of gadgets. It has usability enhancing accessibility features, and it's simple to make alert popups.</p>
<p>It also supports pinch zooming and is compatible with iPads and iPhones.</p>
<h4 id="heading-code-sample-from-reach-ui">Code Sample from Reach UI:</h4>
<p>To get started, you can run this command on your terminal to install the components: <code>npm install @reach/dialog</code>.</p>
<p>To use the components within your application, you can import them like this:</p>
<pre><code><span class="hljs-keyword">import</span> { Dialog, DialogOverlay, DialogContent } <span class="hljs-keyword">from</span> <span class="hljs-string">"@reach/dialog"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@reach/dialog/styles.css"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Dialog</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [showDialog, setShowDialog] = React.useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> open = <span class="hljs-function">() =&gt;</span> setShowDialog(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> close = <span class="hljs-function">() =&gt;</span> setShowDialog(<span class="hljs-literal">false</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">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{open}</span>&gt;</span>Open Dialog<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">Dialog</span> <span class="hljs-attr">isOpen</span>=<span class="hljs-string">{showDialog}</span> <span class="hljs-attr">onDismiss</span>=<span class="hljs-string">{close}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"close-button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{close}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">VisuallyHidden</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">VisuallyHidden</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>&gt;</span>×<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello there. I am a dialog<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Dialog</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre><p>Here's what they look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/screencapture-reach-tech-dialog-2023-08-26-08_37_03.png" alt="The dialog component from the reach ui is placed at the center of the screen" width="600" height="400" loading="lazy">
<em>Dialog component from reach ui</em></p>
<p>To learn more about this library and its components, <a target="_blank" href="https://reach.tech/dialog/">you can check out their documentation here</a>.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>This article highlighted several popular un-styled component libraries, including Radix UI, shadcn's UI Component, Headless UI Library, PrimeReact UI, and Reach UI Dialog Component. </p>
<p>To sum up, using un-styled UI components lets you customize your components according to your needs. It also brings performance efficiency and future adaptability. </p>
<p>These components offer reduced overhead, as they let you use only the components you need. This results in a more efficient application. </p>
<p>The flexibility of un-styled components also lets you tailor elements for specific project requirements, while prioritizing accessibility and user-friendliness. Integrating un-styled UI components elevates your ability to create accessible, visually appealing, and efficient user interfaces.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ TailwindCSS vs NextUI – How to Choose a UI Framework ]]>
                </title>
                <description>
                    <![CDATA[ If you're a developer, choosing the proper UI framework can be tough. This is partly because there are so many options to choose from, each with its strengths and weaknesses.  In this guide, I will discuss the differences between two popular framewor... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tailwindcss-vs-nextui-how-to-choose-a-ui-framework/</link>
                <guid isPermaLink="false">66c4c65399f22436b71945dc</guid>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sophia Iroegbu ]]>
                </dc:creator>
                <pubDate>Tue, 28 Feb 2023 01:20:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/pexels-xxss-is-back-777001--2-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're a developer, choosing the proper UI framework can be tough. This is partly because there are so many options to choose from, each with its strengths and weaknesses. </p>
<p>In this guide, I will discuss the differences between two popular frameworks: Tailwind CSS and NextUI. </p>
<p>Tailwind CSS is a framework that has gained a large following among developers due to its simplicity, flexibility, and ease of use. NextUI, on the other hand, is popular because of its scalability, performance, and flexibility. </p>
<p>This article will compare the critical features of the two frameworks, their pros and cons, and their suitability for different project types. </p>
<p>Whether you are a developer looking to select the best framework for your project or you're just curious about these tools, this article is for you. </p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ul>
<li>What is Tailwind CSS and what are its pros and cons?</li>
<li>What is NextUI and what are its pros and cons?</li>
<li>How to decide between Tailwind and NextUI</li>
</ul>
<p>Let’s dive in! 🚀</p>
<h1 id="heading-what-is-tailwind-css">What is Tailwind CSS?</h1>
<p><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> is a utility-first CSS framework – that is, it's a framework that focuses on functionality rather than its looks or UI. <a target="_blank" href="https://adamwathan.me/">Adam Wathan</a>, a Canadian Software developer and entrepreneur, built Tailwind CSS. </p>
<p>Tailwind allows you to completely customize your utility classes without leaving the HTML. Tailwind CSS offers a fast and easy way to style your websites. </p>
<p>Tailwind CSS is highly customizable. This means as a user, you can modify the fonts, colors and other design elements to match your web design preferences. </p>
<p>This framework also has faster load time because of <a target="_blank" href="https://purgecss.com/">PurgeCSS</a> (which removes unused or unwanted CSS styles from your final build resulting in smaller file sizes). </p>
<h3 id="heading-pros-of-using-tailwind-css">Pros of using Tailwind CSS:</h3>
<p>Just as everything has advantages and disadvantages, here are the advantages of using tailwind CSS:</p>
<ul>
<li>Tailwind is easy to learn and use for first-time developers.</li>
<li>Tailwind uses a few lines of code to create flexible designs.</li>
<li>Tailwind can easily convert a design to reusable components since it is a utility-first framework.</li>
<li>Tailwind is a guide and avoids using unfamiliar names for CSS classes and ids.</li>
<li>Tailwind can effortlessly be customized to suit the developer’s needs.</li>
</ul>
<h3 id="heading-cons-of-using-tailwind-css">Cons of using Tailwind CSS:</h3>
<p>And now here are the disadvantages of using Tailwind CSS:</p>
<ul>
<li>Tailwind contains large CSS files because it provides low-level CSS classes, so when styling, the files may be too large and complex to maintain over time. This also affects the performance of the website or application.</li>
<li>Tailwind may have many low-level classes, but it is hard to override the styles of specific elements when changing designs or styling specific elements.</li>
<li>Tailwind is not always the best framework for some projects. It is undoubtedly a powerful tool, but specific design requirements may not be achievable using the available classes when working on a project. Tailwind is best for projects that involves a lot of styling UI and customizing design elements such as Prototyping, Dashboards, E-commerce websites and lots more.   </li>
</ul>
<h1 id="heading-what-is-nextui">What is NextUI?</h1>
<p><a target="_blank" href="https://nextui.org/">NextUI</a> is a component-based CSS framework, which means it provides a set of pre-designed components you can use at any time. Examples include buttons, forms, navigation bars, navigation menus, and more. </p>
<p>NextUI is built and maintained by the <a target="_blank" href="https://vercel.com/">Vercel</a> team. The beauty of NextUI is that it gives you a customizable template, so you don’t have to write much CSS code to create a responsive website. </p>
<p>The downside of using this framework is that developers won’t have 100% control of the design as the components are limited by NextUI. </p>
<p>In addition to its core UI components, NextUI offers developer tools such as automatic code splitting, server-side rendering, and built-in support for libraries like <a target="_blank" href="https://graphql.org/">GraphQL</a> and <a target="_blank" href="https://www.apollographql.com/">Apollo</a>.  </p>
<h3 id="heading-pros-of-using-nextui">Pros of using NextUI:</h3>
<p>Just as everything has advantages and disadvantages, here are the advantages of using NextUI:</p>
<ul>
<li>NextUI is highly scalable when handling large and complex applications if the application grows. It doesn’t slow down when handling such large files.</li>
<li>NextUI is very flexible and built to suit the user’s needs or tastes.</li>
<li>NextUI has a large, reliable <a target="_blank" href="https://discord.gg/9b6yyZKmH4">community</a> so getting help when using the tool is stress-free.</li>
<li>NextUI has an extensive range of pre-built components and features, which saves the developer's time when building.</li>
<li>NextUI is built on React, making it user-friendly to build a JavaScript application.</li>
</ul>
<h3 id="heading-cons-of-using-nextui">Cons of using NextUI:</h3>
<p>And now here are the disadvantages of using NextUI:</p>
<ul>
<li>NextUI has a large footprint compared to other frameworks despite being built on ReactJS. This can also affect its performance if the developer does not fully understand how to navigate NextUI.</li>
<li>NextUI may not be the best option when building an application that does not involve or use ReactJS.</li>
<li>NextUI may be relatively easy to use but has a learning curve that may be difficult to understand for those who don’t use React.</li>
<li>NextUI requires more attention in setting up and configuration because it offers a range of developer tools for customization.</li>
</ul>
<h1 id="heading-how-to-decide-between-nextui-and-tailwind">How to Decide Between NextUI and Tailwind</h1>
<table>
  <tbody><tr>
    <th>NextUI</th>
    <th>Tailwind CSS</th>
  </tr>
  <tr>
   <td>NextUI was built for rendering React applications.</td>
   <td>Tailwind aims at styling any website or web application easily. </td>
  </tr>
  <tr>
    <td>NextUI CSS is customizable and provides a wide range of developer tools and features to customize the pre-built components to the developer’s needs. </td>
    <td>Tailwind CSS is customizable but the only additional developer tool it provides is PurgeCSS. It doesn't provide tools for querying such as GraphQL.</td>
  </tr>
  <tr>
    <td>NextUI CSS is designed to help developers focus on the performance and scalability of their applications. </td>
    <td>Tailwind CSS is designed to help developers build user interfaces quickly and efficiently. </td>
 </tr>
  <tr>
    <td>NextUI is ideal for large React applications</td>
    <td>Tailwind CSS is ideal for small-scale React appplications</td>
 </tr>
  <tr>
    <td>NextUI CSS provides pre-built UI components and features that can be used to build websites and applications. </td>
    <td>Tailwind CSS provides a wide range of low-level CSS classes. This means tailwind gives the developers chance to build the UI components themselves. </td>
 </tr>
  <tr>
    <td>NextUI CSS may take more time in setting up and configuring.</td>
    <td>Tailwind CSS takes less time in setting up and configuring.</td>
 </tr>
</tbody></table>

<p>If you are working on a React application for a large-scale project, NextUI is the best choice as a CSS framework. But if you are working on an application that requires you to focus on specific functionality or design requirements, Tailwind is the best choice for you.   </p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In conclusion, Tailwind CSS and Next UI are different tools for developing web and mobile applications. </p>
<p>Tailwind CSS is a utility-first CSS framework designed to help developers build a custom user interface quickly. NextUI is a component-based framework designed to help developers improve the performance and scalability of the application. </p>
<p>Tailwind and NextUI each have strengths and weaknesses, and the best choice for your project depends entirely on the application’s design requirements, needs, and goals. </p>
<p>Tailwind CSS best suits developers looking for a simple solution to build a custom user interface. In contrast, NextUI is best suited for developers looking for CSS templates, so they can focus on other parts of the application, like scalability.</p>
<p>In the end, pick the best framework for you based on your preferences and skills as a developer. Before choosing, carefully evaluate the pros and cons of each tool to make an informed decision when building the best possible application for your users.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ UX vs UI – What's the Difference? Definition and Meaning ]]>
                </title>
                <description>
                    <![CDATA[ When designing a website or an app, the finished product needs to be functional, intuitive, and aesthetically pleasing. This is where UX and UI design come in. UX and UI design are two technical terms that can often be confusing. Many people may use ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ux-vs-ui-whats-the-difference-definition-and-meaning/</link>
                <guid isPermaLink="false">66b1e4c841fdb67461b85280</guid>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Fri, 14 Oct 2022 16:15:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/pexels-picjumbocom-196644.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When designing a website or an app, the finished product needs to be functional, intuitive, and aesthetically pleasing. This is where UX and UI design come in.</p>
<p>UX and UI design are two technical terms that can often be confusing.</p>
<p>Many people may use these two terms interchangeably, incorrectly, or assume they are the same thing. But that is not the case, as they are two different fields.</p>
<p>In a nutshell, UX design focuses on how well the product <em>works</em> and how the user <em>feels</em> when using it, whereas UI design focuses on how that software product <em>looks</em>. </p>
<p>Both are equally important and play a vital role when creating and developing software. </p>
<p>Think of it like this: a pretty UI may attract visitors, but if the product is not functional, the visitors won't stick around. And if the product works properly but doesn't look good, users will feel frustrated and look elsewhere to satisfy their needs.</p>
<p>There needs to be a balance.</p>
<p>With that said, the definition above only scratches the surface.</p>
<p>In this article, you will learn about the differences between UX and UI design and understand what UX and UI designers do in their day-to-day work.</p>
<p>Here is what we will cover:</p>
<ol>
<li><a class="post-section-overview" href="#ux-definition">What is UX design and why is it important?</a></li>
<li><a class="post-section-overview" href="#ux-job">What does a UX designer actually do? The UX design process explained</a><ol>
<li><a class="post-section-overview" href="#phase-1">Understanding phase</a></li>
<li><a class="post-section-overview" href="#phase-2">User research phase</a></li>
<li><a class="post-section-overview" href="#phase-3">Analyze and define phase</a></li>
<li><a class="post-section-overview" href="#phase-4">Ideate and design phase</a></li>
<li><a class="post-section-overview" href="#phase-5">Reporting phase</a></li>
</ol>
</li>
<li><a class="post-section-overview" href="#ui-intro">What is UI design?</a><ol>
<li><a class="post-section-overview" href="#ui-skills">What does a UI designer do?</a></li>
</ol>
</li>
<li><a class="post-section-overview" href="#differences">UX VS UI design - what's the difference?</a></li>
</ol>
<h2 id="heading-what-is-ux-design-and-why-is-it-important">What Is UX Design and Why Is It Important? <a></a></h2>
<p>UX design is short for user experience design.</p>
<p>The term was coined and popularized in the early 1990s by Donald Norman, an American researcher, professor, and author, during his time at Apple.</p>
<p>According to Norman:</p>
<blockquote>
<p>User experience encompasses all aspects of the end-user’s interaction with the company, its services, and its products. </p>
</blockquote>
<p>Note that the original definition of UX referred to physical and digital products. Nowadays, UX design mainly relates to digital products. </p>
<p>So, user experience design is a process that involves cultivating a good relationship between a company, the company's software products /services, and the company's clients/customers.</p>
<p>The relationship is based on how a user feels when using the company's products.</p>
<p>UX has to do with feelings, emotions, thoughts, behaviors, and human psychology.</p>
<p>Specifically, good UX depends on the following points:</p>
<ul>
<li>How does a person feel when using the product?</li>
<li>How accessible is it for the person to navigate the product? Can everyone use it?</li>
<li>How usable is the product? Does it work as intended?</li>
<li>How easy is it for the person to navigate and find the necessary information?</li>
<li>How well-planned and intuitive are the steps a user needs to take to accomplish a task?</li>
<li>How logical is the sequence of actions a user needs to perform to accomplish their goal with ease?</li>
<li>Does it make it easy for them to achieve their initial goal?</li>
<li>How well structured is the content available? Does it follow a logical hierarchy?</li>
<li>How useful is the product?</li>
<li>How valuable is the product?</li>
<li>Does it serve a purpose?</li>
</ul>
<p>All of the above are part of what makes good UX design and contribute to the value the software offers.</p>
<p>UX is all about solving problems and always keeping the user in mind.</p>
<p>The end goal is to provide a pleasant and positive experience for the user, create digital products that a user feels comfortable using, and for the user to accomplish their task and have their needs met.</p>
<p>All in all, it focuses on anything and everything that affects the user's journey when trying to solve a problem they have.</p>
<p>Good user experience is vital for every business. If the user/customer is happy and not frustrated, they are more likely to remain loyal.</p>
<p>If users can't use the product with ease, this will result in them giving up on it and looking for an alternative product/service that meets their needs, resulting in a loss for the business. They are unlikely to return to a product after a bad experience.</p>
<h2 id="heading-what-does-a-ux-designer-actually-do-the-ux-design-process-explained">What Does A UX Designer Actually Do? The UX Design Process Explained <a></a></h2>
<p>The UX design process is comprised of many parts. It is a sequential process with the end user always in mind throughout all stages.</p>
<p>The role of a UX designer will vary from business to business and depends on the size of the team they are on. </p>
<p>On a small team, a UX designer will probably be responsible for the whole UX process from start to finish. On a larger team, they might be involved in only one part of the process, such as UX research.</p>
<p>That means a UX designer may not be part of all the stages outlined in the following sections.</p>
<p>Now, let's see the different phases in the UX design process in more detail.</p>
<h3 id="heading-understanding-phase">Understanding Phase <a></a></h3>
<p>The first step in the UX design process is understanding the brand and its users.</p>
<p>Specifically, it is about understanding how the project the UX designer is working on aligns with the brand's mission, vision, and goals. </p>
<p>And it is about understanding the brand's users/customers. </p>
<p>A UX designer can't make assumptions about what the users really want or what problems they are facing when using the product/service. They will only know once they ask the users directly.</p>
<p>The UX designer needs to understand, be in tune with, and empathize with the problems users are facing and their pain points. They need to understand their users' wants and needs.</p>
<p>The key word here is <a target="_blank" href="https://www.freecodecamp.org/news/how-empathy-makes-you-a-better-software-engineer/">empathy</a>! Empathy is the ability to understand the user's hopes, goals, frustrations, and needs. </p>
<p>Once the UX designer has gathered those insights and identified the goals of the brand and the problems the users are facing, they can figure out how to solve problems and provide solutions through their designs and how they can create products/services that solve those problems.</p>
<h3 id="heading-user-research-phase">User Research Phase <a></a></h3>
<p>As mentioned in the section above, a UX designer can't assume, and if they do, they need to question those assumptions by conducting user research.</p>
<p>There are two main methods for conducting user research:</p>
<ul>
<li>Qualitative methods</li>
<li>Quantitative methods</li>
</ul>
<p>Qualitative research methods focus on observational and non-numerical findings, human behaviors, opinions, and emotions. </p>
<p>They include creating customer feedback surveys and asking open-ended questions to understand the key frustrations and pain points and what needs improving.</p>
<p>They also include reaching out to customers directly and conducting 1:1 face-to-face or online user interviews or focus groups of 3-5 target users for usability testing.</p>
<p>Quantitative methods focus on numbers, metrics, and measurable data points. </p>
<p>They include using web analytics tools and researching how the current design is performing. For example, they might find out how many visitors of an e-commerce site are clicking on a particular item and adding it to their cart, or what is the average time spent on the checkout page.</p>
<p>To learn more about user research, check out the following resources:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/why-you-need-a-ux-researcher-on-your-product-team/">Why you need a UX researcher on your product team</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/use-user-reseach-to-create-the-perfect-ui-design/">Use User Research to Create the Perfect UI Design</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/qualitative-vs-quantitative-definition-research-methods-and-data/">Qualitative VS Quantitative Definition – Research Methods and Data</a></li>
</ul>
<h3 id="heading-analyze-and-define-phase">Analyze and Define Phase <a></a></h3>
<p>After gathering user insights, the next phase in the UX design process is for the UX designer to analyze and make sense of all the information and define the problem they need to solve for the user. </p>
<p>They define what their focus should be and what would have the most impact on the users.</p>
<p>At this stage, it is crucial not to lose sight of the user's needs.</p>
<p>For this reason, the UX designer will create user personas based on the research they've gathered.</p>
<p>A user persona is a fictional character that will use the product/service. </p>
<p>It represents a typical target user and identifies their needs, frustrations, behaviors, and goals.</p>
<p>User personas allow UX designers to understand their users better and make wise design decisions.</p>
<p>At this stage, a UX designer might also create use cases. </p>
<p>A use case is a description of how different users might use and interact with the product or service.</p>
<p>Finally, a UX designer might also create journey maps.</p>
<p>A journey map is a visual and graphic representation of how the user will interact with the product/service from start to finish, and a map depicting the whole user journey until the user accomplishes their goal. </p>
<p>Journey maps are useful for understanding the different pain points a user faces when using the product and where those pain points occur, which leads to restructuring the product/service.</p>
<p>To learn more about user personas and use cases, check out the following resources:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-user-stories-epics-pesonas/">How To Write User Stories, Epics, &amp; Personas</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/use-cases-and-organizational-structure/">Use cases and organizational structure</a></li>
</ul>
<h3 id="heading-ideate-and-design-phase">Ideate and Design Phase <a></a></h3>
<p>The ideate phase is all about brainstorming and exploring out-of-the-box design ideas.</p>
<p>At this stage, the UX designer will come up with different creative options for how to solve the problem at hand.</p>
<p>They will brainstorm ideas and sketch them on paper before using any digital tools.</p>
<p>They will also create wireframes. Wireframes are rough prototypes and visual representations of what the UI and its various components will look like and which act as a guide and direction for the final design.</p>
<p>They will outline the steps and the complete path a user will take while using the product/service.</p>
<p>The end goal of this phase of the UX design process is to design low or high-fidelity versions of the structure and layout of the product (which may or may not be interactive) and of what the final design will look like. The first design is never the final design.</p>
<p>After continuously iterating the designs, adding new ideas and features,  rigorous testing, and feedback, the UX designer will have a detailed and carefully crafted digital mockup.</p>
<p>The mockup will look almost identical to the final product, which they hand off to the engineering team. The engineering team will build and ship the real-world working product.</p>
<p>To learn more about creating wireframes, check out the following resources:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/what-is-a-wireframe-ux-design-tutorial-website/">What is a Wireframe? This UX Design Tutorial Will Show You.</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/designing-a-website-ui-with-prototyping/">How to Design a Website Prototype from a Wireframe</a></li>
</ul>
<h3 id="heading-reporting-phase">Reporting Phase <a></a></h3>
<p>After the product launches, the next phase of the UX design process is the reporting phase. This includes conducting usability testing, observing how users are using the end product, collecting feedback, and gaining additional insights.</p>
<p>This phase helps the UX designer and their teams understand if the end product solves the initial problem and if it meets the needs of their end users.</p>
<p>At this phase, here are some of the questions that a UX designer may ask:</p>
<ul>
<li>"What did we do right?"</li>
<li>"What <em>didn't</em> we do right, and why?" </li>
<li>"What did we learn?"</li>
<li>"How can we improve in the future?"</li>
<li>"How are users responding to the product/service? Did we solve their problems and pain points?"</li>
</ul>
<p>With that said, the UX design process doesn't end here, since there are continuous iterations and improvements to be made.</p>
<h2 id="heading-what-is-ui-design-and-why-its-important-an-overview-of-ui-design">What Is UI Design and Why It's Important? An Overview of UI Design   <a></a></h2>
<p>So far, you have seen that UX design involves every aspect of a user’s experience when using a product. So what exactly is UI design, then?</p>
<p>Back in the 1970s, to use a computer, you had to use a command line interface (or CLI for short), and users needed to know a programming language to communicate with the machine. </p>
<p>At that time, you needed a lot of technical knowledge and skills to complete a simple task with a computer.</p>
<p>That changed in the 1980s with the introduction of Graphical User Interfaces (or GUIs for short) and personal computers. </p>
<p>A mouse, application icons, buttons, menus, checkboxes, and folders replaced the cryptic command line. Anyone could use a computer. Users could easily create, update, move, and delete files and send emails – no coding required.</p>
<p>The people that created these early graphical user interfaces were called User Interface (or UI for short) designers.</p>
<p>Nowadays, the term user interface involves every visual part of a digital product/service that a user interacts with. This includes mobile apps, websites, screens, touchscreens, keyboards, and wearable technology such as smartwatches, to name a few.</p>
<p>You can think of it as the bridge between the user and technology.</p>
<p>A UI designer is responsible for designing every step that allows a user to interact with the digital product/service. This includes layouts, structure, buttons, colors, and animations.</p>
<p>UI design is all about the <em>look,</em> <em>feel</em>, and <em>aesthetics</em> of a digital product. It involves every visual aspect and appearance of the product the user interacts with.</p>
<p>The end goal of a UI designer is to make something visually appealing to the user that's easy to interact with.</p>
<p>Good UI is vital for drawing attention to potential customers and attracting new users. Everyone appreciates a well-designed, clean, intuitive, and modern design.</p>
<p>But how does all this relate to UX design? You can think of UI design as a subset of UX design and a small part of the UX design process. But it is a separate discipline in its own right. </p>
<h3 id="heading-what-does-a-ui-designer-do-ui-design-skills-definition-and-examples">What Does A UI Designer Do? UI Design Skills Definition and Examples <a></a></h3>
<p>UI designers need to have visual design skills.</p>
<p>Specifically, they need to know the following concepts and disciplines:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-increase-user-engagement-with-your-app-using-color-theory-7c6f5c632570/">Color theory</a>, creating color palettes and creating accessible contrast that ensures both usability and readability.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-design-good-typography/">Typography</a>.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-layout-and-design-a-website-without-any-design-skills-86d94e40b55a/">Layout</a>, spacing, structure, and effective placement of elements on a page.</li>
<li>Graphics, icons, and illustration design.</li>
<li>Interaction design principles, animation effects, and motion design.</li>
<li>Branding – creating a consistent visual identity for a brand/product and communicating the brand's mission and message.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/master-responsive-website-design/">Responsive design</a>, and ensuring the UI looks good on all screen sizes and devices.</li>
<li>Creating <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-style-guide-in-figma/">style guides</a>.</li>
<li>Creating <a target="_blank" href="https://www.freecodecamp.org/news/learn-how-to-create-a-design-system-in-figma/">design systems</a>.</li>
<li>Knowledge of industry tools such as <a target="_blank" href="https://www.freecodecamp.org/news/ui-design-with-figma-tutorial/">Figma</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/ui-ux-design-tutorial-from-zero-to-hero-with-wireframe-prototype-figma/">Wireframing and prototyping</a>.</li>
</ul>
<h2 id="heading-ux-vs-ui-design-whats-the-difference-the-difference-between-ux-and-ui-design-explained-in-plain-english">UX VS UI Design – What's the Difference? The Difference Between UX and UI Design Explained in Plain English <a></a></h2>
<p>By this point, you hopefully understand what UX and UI design involves.</p>
<p>To summarize their differences:</p>
<p>UX design is how things <em>work</em> and how <em>useful</em> they are. UX design focuses on the whole experience and the journey a user takes when using a product from start to finish. It involves the overall experience a user has when trying to solve a problem. </p>
<p>UX requires knowledge of psychology, cognitive science, human behavior, identifying the user's pain points, and solving their problems.</p>
<p>UI design is how things <em>look</em>. UI design is a subset of UX design and is a more specialized field. It focuses only on the visual aspects that a user interacts with and creates inclusive, accessible, pleasant, and aesthetically pleasing digital interfaces. </p>
<p>UI design also focuses on creating a brand aesthetic that leads to an emotional connection with users/customers.</p>
<p>Both UX and UI design are equally important in creating useful, usable, and modern digital products and services and meeting the needs of their users.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This marks the end of the article – thank you so much for making it to the end!</p>
<p>Hopefully, this guide was helpful, and it gave you some insight into what UX and UI design are, what UX and UI designers do in their day-to-day work, and what the differences between those two terms are.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Any UI in Flutter ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you will learn how to convert any user interface image, piece, or screen into Flutter code. This is not a tutorial on building an app. It is rather a guide that will help you implement any UI you come across into an app you already h... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-any-ui-in-flutter/</link>
                <guid isPermaLink="false">66b9ff4c85b28e0b24537e57</guid>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Obum ]]>
                </dc:creator>
                <pubDate>Wed, 08 Jun 2022 15:22:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/anyuicover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you will learn how to convert any user interface image, piece, or screen into <a target="_blank" href="https://flutter.dev">Flutter</a> code.</p>
<p>This is not a tutorial on building an app. It is rather a guide that will help you implement any UI you come across into an app you already have. This tutorial also explains a wide variety of UI concepts in Flutter.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-flutter">What is Flutter?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-widgets-in-flutter">Widgets in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-widget-tree">The Widget Tree</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-any-ui-in-flutter">How to Implement any UI in Flutter</a><br>  <a class="post-section-overview" href="#heading-1-write-your-code-starting-at-the-top-left-and-move-down-to-the-bottom-right">1. Implement Top Left; Down Right</a><br>  <a class="post-section-overview" href="#heading-2-choose-a-widget">2. Choose a Widget</a><br>  <a class="post-section-overview" href="#heading-3-use-widget-groups">3. Use widget groups</a><br>  <a class="post-section-overview" href="#heading-a-columnrow">a. Column/Row</a><br>  <a class="post-section-overview" href="#heading-b-stack-widget">b. Stack Widget</a><br>  <a class="post-section-overview" href="#heading-4-create-custom-widgets">4. Create custom widgets</a><br>  <a class="post-section-overview" href="#heading-5-add-more-customization">5. Add more customization</a><br>  <a class="post-section-overview" href="#heading-a-container-widget">a. Container Widget</a><br>  <a class="post-section-overview" href="#heading-b-gesturedetector-inkwell">b. GestureDetector / InkWell</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-scrolling-interfaces">How to Implement Scrolling Interfaces</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-about-custompaint">About CustomPaint</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-what-is-flutter">What is Flutter?</h2>
<blockquote>
<p>Flutter is an open source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase. – (s<a target="_blank" href="https://flutter.dev">ource: flutter.dev</a>)</p>
</blockquote>
<p>In Flutter, contrary to most frameworks, <a target="_blank" href="https://dart.dev">Dart</a> is the only programming language you use to code. This is an underemphasized benefit of Flutter. Especially for a tool that can build desktop, mobile, and web applications.</p>
<p>Most <a target="_blank" href="https://en.wikipedia.org/wiki/User_interface_design">UI</a> platforms use more than one language. For example, in front-end web development, you have to write <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML">HTML</a>, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS">CSS</a>, and <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript</a>. For <a target="_blank" href="https://developer.android.com/">Android</a>, you have to write <a target="_blank" href="https://developer.android.com/kotlin">Kotlin</a> (or <a target="_blank" href="https://developer.android.com/studio/write/java8-support">Java</a>) and <a target="_blank" href="https://developer.android.com/guide/topics/ui/declaring-layout#write">XML</a>. But in Flutter, it's just one language: Dart.</p>
<p>Coupled with the only-one-programming-language benefit, Flutter is simple because everything in Flutter is a widget. For example <a target="_blank" href="https://api.flutter.dev/flutter/widgets/AnimatedWidget-class.html">AnimatedWidget</a>, <a target="_blank" href="https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html">BottomNavigationBar</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container-class.html">Container</a>, <a target="_blank" href="https://api.flutter.dev/flutter/material/Drawer-class.html">Drawer</a>, <a target="_blank" href="https://api.flutter.dev/flutter/material/ElevatedButton-class.html">ElevatedButton</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/FormField-class.html">FormField</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Image-class.html">Image</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Opacity-class.html">Opacity</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Padding-class.html">Padding</a>, ...</p>
<p>This is part of what makes Flutter easy to use – it's basically plain English. <a target="_blank" href="https://docs.flutter.dev/development/ui/widgets">Widget</a> names reflect what they are and their properties are easy to understand.</p>
<h2 id="heading-widgets-in-flutter">Widgets in Flutter</h2>
<p>A widget is a Dart <a target="_blank" href="https://dart.dev/samples#classes">class</a> that either extends <a target="_blank" href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html">StatefulWidget</a> or <a target="_blank" href="https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html">StatelessWidget</a>.</p>
<p>Your local <a target="_blank" href="https://docs.flutter.dev/get-started/install">Flutter installation</a> comes with several widgets. To check out the widgets available by default, open the packages folder of your Flutter installation in your preferred editor. Then search across all files for "extends StatefulWidget" and "extends StatelessWidget" and take note of the number of results.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/flutter-packages-widget-count.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As of <a target="_blank" href="https://docs.flutter.dev/development/tools/sdk/release-notes/release-notes-2.10.0">Flutter 2.10</a>, you will get <strong>408</strong> StatefulWidgets and <strong>272</strong> StatelessWidgets. That is a total of <strong>680 widgets</strong> available for you to use and implement UIs.</p>
<p>These widgets typically have all you need. But at times they may not be enough. <a target="_blank" href="https://pub.dev">pub.dev</a>, Dart and Flutter's package manager, have many more widgets you can use to implement UIs.</p>
<p>It is difficult to count the widgets in pub.dev. But searching an empty string (don't enter anything in the search bar and then press the search icon) and setting the SDK to Flutter returns the current total number of published packages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/pub.dev-widget-count.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At the time of writing, there are more than 23000 Flutter packages in pub.dev. Each package has <em>at least one</em> widget. This means that you have more than 23000 widgets from pub.dev to implement, in addition to the available 680. This means that you can really implement any UI you want easily in Flutter.</p>
<p>Adding to the many available widgets, you can also create your own widgets as you implement UIs.</p>
<h2 id="heading-the-widget-tree">The Widget Tree</h2>
<p>The following is part of the code you get when you create a new Flutter project and remove the comments:</p>
<pre><code class="lang-dart"> <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: &lt;Widget&gt;[
            <span class="hljs-keyword">const</span> Text(
              <span class="hljs-string">'You have pushed the button this many times:'</span>,
            ),
            Text(
              <span class="hljs-string">'<span class="hljs-subst">$_counter</span>'</span>,
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: <span class="hljs-string">'Increment'</span>,
        child: <span class="hljs-keyword">const</span> Icon(Icons.add),
      ),
    );
  }
</code></pre>
<p>The parent <code>Scaffold</code> takes the <code>appBar</code>, <code>body</code>, and <code>floatingActionButton</code> parameters. In turn, the <a target="_blank" href="https://api.flutter.dev/flutter/material/AppBar-class.html">AppBar</a> also takes a <code>title</code> parameter that has a <code>Text</code> value.</p>
<p><code>body</code> takes a <code>Center</code> value that has a <code>Column</code> <code>child</code>. The <code>Column</code> in turn has two <code>Text</code>s as <code>children</code>. The <code>FloatingActionButton</code> takes the <code>onPressed</code> callback, 'Increment' <code>tooltip</code>, and an <code>Icon</code> for a <code>child</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot--142--2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Flutter widget tree breakdown</em></p>
<p>This is a simple widget tree. It has parents and descendants. <code>child</code> and <code>children</code> are common properties of most Flutter widgets. As widgets continuously take more widget children, your app gradually grows into a large widget tree.</p>
<p>As you implement UIs in Flutter, bear in mind that you are building a widget tree. You will notice that your code indents inwards from the left margin. It seems to develop some kind of virtual greater than sign (of empty space) at the left.</p>
<p><strong>Note:</strong> Huge indentation levels are a sign that you need to refactor your code. It means that you need to extract some widget hierarchy into a separate widget.</p>
<h2 id="heading-how-to-implement-any-ui-in-flutter">How to Implement Any UI in Flutter</h2>
<h3 id="heading-1-write-your-code-starting-at-the-top-left-and-move-down-to-the-bottom-right">1. Write your code starting at the top left and move down to the bottom right</h3>
<p>You'll implement the UI widget after widget according to each element's position in the UI. So you will first write code for things that appear at the top of the UI. Then you keep writing code for the other items moving down the page until you reach the bottom of that UI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot--143-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is intuitive.</p>
<p>On the horizontal axis, go from left to right. If need be, or if it is a <a target="_blank" href="https://medium.com/@carlolucera/flutter-and-directionality-d9ac42197fb8">right-to-left</a> UI, then implement it from right to left instead.</p>
<h3 id="heading-2-choose-a-widget">2. Choose a Widget</h3>
<p>Next you'll need to logically determine the widget you want to use for a given UI element. At a bare minimum, for a given UI element, you will use simple widgets you're familiar with based on what their names say they do.</p>
<p>Chances are the name of what the UI component looks like is the name of the widget. If you find it hard to make a choice, a quick online search will give you the answers. Flutter has a great online community.</p>
<h3 id="heading-3-use-widget-groups">3. Use widget groups</h3>
<p>If a group of UI items is arranged vertically, one after another, use a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Column-class.html">Column</a>. If they are arranged horizontally, one after another, use a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Row-class.html">Row</a>. If they are placed on top of each other, use a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Stack-class.html">Stack</a>, with the floating widgets wrapped in <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned-class.html">Positioned</a> widgets.</p>
<h4 id="heading-a-columnrow">a. Column/Row</h4>
<p>Inside a Column or Row, you can change or adjust how the widgets will align themselves on the main or cross axis. Use their <a target="_blank" href="https://api.flutter.dev/flutter/rendering/CrossAxisAlignment.html">CrossAxisAlignment</a> and <a target="_blank" href="https://api.flutter.dev/flutter/rendering/MainAxisAlignment.html">MainAxisAlignment</a> properties for such adjustments.</p>
<p>For the cross axis, you can align to center, end, start, and stretch. For the main axis, you can align to center, end, space around, space between, space evenly, and end.</p>
<p>In a <code>Column</code>, the vertical axis is the main axis while the horizontal axis is the cross axis. In a <code>Row</code>, the horizontal axis is the main axis while the vertical axis is the cross axis.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/1Untitled-1-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Adapted from https://arzerin.com/2019/11/20/flutter-column/</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Untitled-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Adapted from https://arzerin.com/2019/11/20/flutter-row/</em></p>
<p>In Columns and Rows, if you want a particular child widget to take as much available space as possible, wrap that widget inside an <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Expanded-class.html">Expanded</a> widget. If you are familiar with web frontend, you'll notice that Columns and Rows are like <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/flex">display: flex;</a> in CSS.</p>
<h4 id="heading-b-stack-widget">b. Stack Widget</h4>
<p>With <code>Stack</code>, the last widget(s) in the <code>children</code>'s list appears on top of the earlier children.</p>
<p>You might have to edit the Stack's <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Stack/alignment.html">alignment</a> to indicate the relative positions of the widgets. Like <a target="_blank" href="https://api.flutter.dev/flutter/painting/AlignmentDirectional/topCenter-constant.html">topCenter</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/AlignmentDirectional/center-constant.html">center</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/AlignmentDirectional/bottomEnd-constant.html">bottomEnd</a>, and so on.</p>
<p>The Stack's size is calculated based on non-positioned widgets (Widgets in the children list not wrapped in a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned-class.html">Positioned</a> parent). When coding, remember that your Stack should either have at least one non-positioned widget, or it should be wrapped in a parent widget that explicitly sets the Stack's size.</p>
<p>Positioned takes any or all of <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned/bottom.html">bottom</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned/top.html">top</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned/left.html">left</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Positioned/right.html">right</a>. They set the child's position relative to the Stack. Negative values move the child in the opposite direction. However, negative values clip parts of the child out. Use <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Stack/clipBehavior.html">clipBehavior: Clip.none</a> on the Stack to show all the parts of the positioned widget.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/Screenshot--148-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Full code</em> <a target="_blank" href="https://gist.github.com/obumnwabude/de06d67b7e636dfb8ae1b852b97624b4"><em>here</em></a><em>.</em></p>
<h3 id="heading-4-create-custom-widgets">4. Create custom widgets</h3>
<p>As you build the widget tree, you will notice two things:</p>
<ol>
<li><p>Either a chunk of the tree grows too big and it is a logical unit on its own.</p>
</li>
<li><p>Or some chunks or sets of widgets might repeat themselves with slight changes.</p>
</li>
</ol>
<p>These are two indications that you should <a target="_blank" href="https://en.wikipedia.org/wiki/Code_refactoring">refactor</a> your code. It means that you should extract out those widgets and define them in another Dart file.</p>
<p>Your <a target="_blank" href="https://docs.flutter.dev/get-started/editor">code editor</a> will help you with refactoring. With or without the editor, all you need to do is:</p>
<ol>
<li><p>Create a new Dart file. The file name should reflect the new widget's name.</p>
</li>
<li><p>Create a new class that extends StatefulWidget or StatelessWidget, depending on if the new widget has <a target="_blank" href="https://api.flutter.dev/flutter/widgets/State-class.html">State</a> or not.</p>
</li>
<li><p>Then return the widget chunk from a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/StatelessWidget/build.html">build</a> method.</p>
</li>
<li><p>(Optional) If need be, your new Dart class can take positional or named parameters to its constructor to customize the widget's look.</p>
</li>
</ol>
<pre><code class="lang-dart"><span class="hljs-comment">// in counter_display.dart</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CounterDisplay</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Column(
        mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(<span class="hljs-string">'You have pushed the button this many times:'</span>),
        Text(<span class="hljs-string">'<span class="hljs-subst">$counter</span>'</span>, style: TextStyle(fontSize: <span class="hljs-number">24</span>)),
      ],
    );
  }
}

<span class="hljs-comment">// in main.dart</span>
<span class="hljs-comment">//</span>
<span class="hljs-comment">// ... </span>
  body: Center(child: CounterDisplay()),
<span class="hljs-comment">// ...</span>
</code></pre>
<p>You will build many custom widgets and they in turn will be descendants to more custom widgets, and that's fine. The widget tree is meant to continuously grow as the need arises.</p>
<h3 id="heading-5-add-more-customization">5. Add more customization</h3>
<p>You won't customize widgets only because of refactoring and <a target="_blank" href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">repetitions (DRY code)</a>. You will create custom widgets because of the UI you are implementing.</p>
<p>You will create custom widgets because the many available widgets don't always meet the exact needs of a given UI. You'll need to combine them in some special way to implement a particular UI.</p>
<h4 id="heading-a-container-widget">a. Container Widget</h4>
<p><a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container-class.html">Container</a> is a powerful widget. You can style it in different ways. If you are used to web frontend, you'll notice that it is like a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div">div</a> in HTML.</p>
<p>Container is a base widget. You can use it to create any UI piece.</p>
<p>Some Container parameters are <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/constraints.html">constraints</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/decoration.html">decoration</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/margin.html">margin</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/padding.html">padding</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/transform.html">transform</a>, among others. Of course, Container takes a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/Container/child.html">child</a> which can be any widget.</p>
<p>The decoration property can take a <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration-class.html">BoxDecoration</a>, which in turn can take several other properties. This is the heart of Container's flexibility. BoxDecoration takes parameters like <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/border.html">border</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/borderRadius.html">borderRadius</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/boxShadow.html">boxShadow</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/color.html">color</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/gradient.html">gradient</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/image.html">image</a>, <a target="_blank" href="https://api.flutter.dev/flutter/painting/BoxDecoration/shape.html">shape</a>, among others.</p>
<p>With these parameters and their values, you can implement any UI to your taste. You can use <code>Container</code> instead of the many <a target="_blank" href="https://api.flutter.dev/flutter/material/material-library.html">material widgets</a> that Flutter comes with. That way your app is to your taste.</p>
<h4 id="heading-b-gesturedetector-inkwell">b. GestureDetector / InkWell</h4>
<p><a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector-class.html">GestureDetector</a> as the name implies detects user interactions. Not every UI piece is a button. And while implementing UIs you will need some widgets to react to user actions. In such a case, use GestureDetector.</p>
<p>GestureDetector can detect different types of gestures: taps, double taps, swipes, ... GestureDetector of course takes a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector/child.html">child</a> (which can be any widget), and different callbacks for different gestures like <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector/onTap.html">onTap</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html">onDoubleTap</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html">onPanUpdate</a> (for swipes), ...</p>
<p>Note: By default, when users interact with the empty spaces in the child of GestureDetectors, the callbacks are not called. If you want your GestureDetector to react to gestures on empty space (within its child), then set the <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GestureDetector/behavior.html">behavior</a> property of the GestureDetector to <a target="_blank" href="https://api.flutter.dev/flutter/rendering/HitTestBehavior.html">HitTestBehavior.translucent</a>.</p>
<pre><code class="lang-dart">GestureDetector(
  <span class="hljs-comment">// set behavior to detect taps on empty spaces</span>
  behavior: HitTestBehavior.translucent,
  child: Column(
    children: [
      Text(<span class="hljs-string">'I have space after me ...'</span>),
      SizedBox(height: <span class="hljs-number">32</span>),
      Text(<span class="hljs-string">'... that can detect taps.'</span>),
    ],
  ),
  onTap: () =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">'Tapped on empty space.'</span>),
)
</code></pre>
<p><a target="_blank" href="https://api.flutter.dev/flutter/material/InkWell-class.html">InkWell</a> is similar to GestureDetector. It responds to some gestures that GestureDetector responds to. However, it shows ripple effects when interacted with (which GestureDetectors don't).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/QqEZ3.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>From https://stackoverflow.com/q/58285012/13644299</em></p>
<p>InkWell must have a <a target="_blank" href="https://api.flutter.dev/flutter/material/Material-class.html">Material</a> ancestor. So, if your topmost widget is <a target="_blank" href="https://api.flutter.dev/flutter/material/MaterialApp-class.html">MaterialApp</a> you need not worry. Else, wrap the InkWell in a Material.</p>
<p>You should also do this wrapping if you are changing the colors of the InkWell's parent or child. If you don't, the ripple won't show. You also have to set the <a target="_blank" href="https://api.flutter.dev/flutter/material/Material/color.html">color</a> of the Material widget for the ripple to show. You can set the color to <a target="_blank" href="https://api.flutter.dev/flutter/material/Colors/transparent-constant.html">Colors.transparent</a> and Flutter will take care of the rest.</p>
<h2 id="heading-how-to-implement-scrolling-interfaces">How to Implement Scrolling Interfaces</h2>
<p>Scrolling is a little delicate topic. By default, widgets don't scroll in Flutter. If your Column or Row will be scrollable, use a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/ListView-class.html">ListView</a> instead. ListView takes children parameter too.</p>
<p>ListView also has factory constructors like <a target="_blank" href="https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html">ListView.builder</a> and <a target="_blank" href="https://api.flutter.dev/flutter/widgets/ListView/ListView.separated.html">ListView.separated</a>. The builder gives you more control over the build process of the children whereas the separated takes into account a Separator (like <a target="_blank" href="https://api.flutter.dev/flutter/material/Divider-class.html">Divider</a> for example).</p>
<p>By default, ListViews scroll their children vertically. However, you can change the <a target="_blank" href="https://api.flutter.dev/flutter/widgets/ScrollView/scrollDirection.html">scrollDirection</a> of a ListView to <a target="_blank" href="https://api.flutter.dev/flutter/painting/Axis.html">Axis.horizontal</a> to scroll its children horizontally.</p>
<p>At times, you might want to use <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html">SingleChildScrollView</a> instead of ListView. As the name implies, it takes a single <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SingleChildScrollView/child.html">child</a> and it can scroll. You can pass widget groups as its child.</p>
<p><a target="_blank" href="https://docs.flutter.dev/development/ui/widgets/scrolling">There are other scrolling widgets</a>.</p>
<p>But take special note of <a target="_blank" href="https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html">CustomScrollView</a>. It gives you huge control of scrolling, unlike the others. It takes <a target="_blank" href="https://api.flutter.dev/flutter/widgets/CustomScrollView/slivers.html">slivers</a>, which in turn are scrolling widgets with powerful scroll mechanisms.</p>
<p><a target="_blank" href="https://api.flutter.dev/flutter/widgets/SliverFillRemaining-class.html">SliverFillRemaining</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SliverFillViewport-class.html">SliverFillViewport</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SliverGrid-class.html">SliverGrid</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SliverList-class.html">SliverList</a>, <a target="_blank" href="https://api.flutter.dev/flutter/widgets/SliverPersistentHeader-class.html">SliverPersistentHeader</a> among others, are examples of widgets you include in the list of slivers. Most of these widgets take a delegate, which handles how scrolling occurs.</p>
<p>A good case to use CustomScrollView is with <a target="_blank" href="https://api.flutter.dev/flutter/material/SliverAppBar-class.html">SliverAppBar</a>, where you want the AppBar to be expanded by default and shrunk on scroll.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/ap.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Another example could be with a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/DraggableScrollableSheet-class.html">DraggableScrollableSheet</a> where you keep some action button sticked to the bottom.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/bs.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-about-custompaint">About CustomPaint</h2>
<p>This is where Flutter gave ultimate flexibility to the UI world.</p>
<p><a target="_blank" href="https://api.flutter.dev/flutter/widgets/CustomPaint-class.html">CustomPaint</a> is to Flutter what the Canvas API is to HTML or SVG is to images.</p>
<p>CustomPaint is a widget in Flutter that gives you the ability to design and draw without limitations. It gives you a canvas on which you can draw with a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/CustomPaint/painter.html">painter</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/visualizer.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>From https://blog.codemagic.io/flutter-custom-painter/</em></p>
<p>You will rarely use CustomPaint. But be aware that it exists. Because there might be very complex UIs that widget combinations might not implement them and you will have no choice than drawing with <code>CustomPaint</code>.</p>
<p>When that time comes, it won't be hard for you because you are already familiar with other widgets.</p>
<h2 id="heading-summary">Summary</h2>
<p>For a given UI piece, choose a widget, write its code, build the widget with other widgets, and see what great UI you are implementing with Flutter.</p>
<p>Implementing UIs is a major part of mobile, web, and desktop app development. Flutter is a UI toolkit that build cross-platform for those platforms. Flutter's declarative nature and its widget abundance make UI implementation simple.</p>
<p>Keep implementing UIs in Flutter. As you do, it will become second nature to you. And you will be able to implement any UI in Flutter.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Use User Research to Create the Perfect UI Design ]]>
                </title>
                <description>
                    <![CDATA[ If you want to design your app in the best way possible, it is important to really understand the needs of your users. This can be done through user research. We just published a UI / UX design course on the freeCodeCamp.org YouTube channel that will... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-user-reseach-to-create-the-perfect-ui-design/</link>
                <guid isPermaLink="false">66b206ebdc300c9dddc01286</guid>
                
                    <category>
                        <![CDATA[ figma ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 02 Feb 2022 19:17:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/app-desgin.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you want to design your app in the best way possible, it is important to really understand the needs of your users. This can be done through user research.</p>
<p>We just published a UI / UX design course on the freeCodeCamp.org YouTube channel that will teach you how to use Figma to design a web app based on the needs of users.</p>
<p>Joseph Brendan developed this course. Joseph is a great instructor who has taught thousands of people on his YouTube channel. </p>
<p>In this course you will learn how to use the d.school design thinking process and self process management to come up with design solutions. You will develop a Fintech app from scratch.</p>
<p>Here are the sections in this course:</p>
<ul>
<li>Outline Breakdown</li>
<li>Workflow Breakdown In FigJam</li>
<li>User Empathy ( Empathize )</li>
<li>Creating User Experience Survey With Google Forms</li>
<li>Creating User Personas</li>
<li>Creating Problem Statement</li>
<li>Ideate</li>
<li>Prototype Analysis</li>
<li>User Goals &amp; User Tasks</li>
<li>Information Architecture</li>
<li>Low Fidelity Prototyping</li>
<li>High Fidelity Prototyping</li>
<li>Creating Style Library</li>
<li>Creating Component Library</li>
<li>Prototype Presentation &amp; Assignments</li>
</ul>
<p>Watch the full course below or on <a target="_blank" href="https://youtu.be/YD0egXpd-Y0">the freeCodeCamp.org YouTube channel</a> (2-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/YD0egXpd-Y0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-transcript">Transcript</h3>
<p>(autogenerated)</p>
<p>In this course you will improve your user interface and user experience design skills by building a mobile app.</p>
<p>Instructor, Joseph Brendan is a great designer and great teacher.</p>
<p>Hey, guys, my name is Joseph, Brandon.</p>
<p>And in this course, I am going to show you how to design a mobile app from scratch.</p>
<p>Now, this mobile app will be a stock investing mobile app that users can use to invest in the stocks of companies that they would like to invest in.</p>
<p>So here is a demonstration of the app that we are going to design.</p>
<p>Now over here, we have the splash screen of the app, which is what's going to show up when you launch the app.</p>
<p>Now, let's go to the next page here.</p>
<p>Now, this is the page where the user will have to select their next action, which is either to log in as an existing user or to get started as a new user.</p>
<p>So I'll go ahead and click on get started, just like a new user would do.</p>
<p>And here on this page, the new user will be required to sign up to this application with an email address, a phone number and a password.</p>
<p>Now, when the new user doors that the new user will be taken to this page, where the new user will have to enter a verification code that's been sent to the phone number of that new user.</p>
<p>Now, when the phone number of the new user is verified, it means that the new user is now a registered user on this application, and the next thing the user is going to do is to click on the Proceed button here.</p>
<p>And when the user does that, the user will be taken to the homepage of the application, which is this page here.</p>
<p>And here on the homepage of this application.</p>
<p>Over here, the account balance of the user will be displayed here.</p>
<p>Also, the user will have a button here that can be used to fund the account on this application.</p>
<p>And right over here, the user will have a list of recent transactions that they have carried out on this application.</p>
<p>Now coming down here, the user will see a banner here that they can click on to get a referral link that can be used to invite friends to have an account on this app.</p>
<p>Now, at the bottom here, we have the navigation section of this app.</p>
<p>Currently, we are on the homepage of the app.</p>
<p>Now let's navigate to the InVEST page, which is the page where the user will have the features that they can use to invest in stocks.</p>
<p>So I'd come here, and I'll click on invest.</p>
<p>When I do that, I'll be taken to the InVEST page, which is this.</p>
<p>And over here on the InVEST page, you can see that we have a display of cash and assets owned by the user.</p>
<p>And right after that, over here, we have a list of top stocks that the user can invest in.</p>
<p>And also, we have the investment portfolio of that user over here, which is a list of all the investments that the user had made on this app.</p>
<p>Now let's say the user is trying to invest in one of the stocks listed here, let's say this one, yeah.</p>
<p>Now, if the user clicks on it, the user will be taken to the details page of that stock that they clicked on.</p>
<p>And on this details page, we are going to have information about the stock and the company that owns the stock.</p>
<p>Now if the user likes what they see here, the user will go ahead to click on the InVEST button here.</p>
<p>And when the user clicks on that button, the user will be required to enter the amount that they wish to invest in that stocks with.</p>
<p>Now when the user enters the amount and the user clicks on the Proceed button here, the user will see a summary of the investment that they are about to make.</p>
<p>And when the user is okay with what they see here in the summary.</p>
<p>The user will be required to enter their secrets pin here, and then click on the InVEST button here.</p>
<p>And when the user does that, it means that the investment has been successful.</p>
<p>So this app that I just demonstrated here is what we are going to design in this course from scratch.</p>
<p>Now before we start designing this app, I would love to break down the stages of our workflow for this project, so that you can understand In the execution process of designing products that are actual business solutions.</p>
<p>So here are the stages of our workflow.</p>
<p>First things first, the stakeholders of this project, which is the owner of the project, or the company we are working for, will present us with a problem that they would want us to design for.</p>
<p>Now, when they present these problems on us, they are also going to tell us about the users, which are the people facing the problem that they want us to design for.</p>
<p>Now, after that, the stakeholders will state their expected goals for the project.</p>
<p>Now after the stakeholders presents a problem and states, their expected goals to us, the next stage of our workflow will be for us, the UX designers to empathize with the users.</p>
<p>Now after we empathize with the users patient problem, we are going to create what we call a problem statement.</p>
<p>And after creating this problem statements, the next stage of our workflow will be the stage where we will have to come up with ideas that can be best business solutions to the problems highlighted in the problem statement.</p>
<p>Now, when we are able to get an idea for the problems in the problem statement, the next action will be for us to design that idea into a testable prototype.</p>
<p>And after designing that idea into a testable prototype, we will go ahead to test the design to be sure that it is able to solve the problems in the problem statement.</p>
<p>So let's get to work.</p>
<p>Now outcome here in figma.</p>
<p>And I'll use a fig jam file to walk on all the analytical parts of our workflow.</p>
<p>So let's create a fig jam file.</p>
<p>And to do that, come here and click on the new fig jam File button there.</p>
<p>When you do that, you have created a junk file as easy as that.</p>
<p>And I'd like to mention that if you are new to using fie jam, you have nothing to worry about.</p>
<p>It's a really simple tool to use.</p>
<p>Just follow along, and you'd see that at the end of this course, you would be good with using feature.</p>
<p>So I'll close this.</p>
<p>And the next thing I'll do after creating a fifth gem file is to give the fifth gem file a name.</p>
<p>So I'll call this stocks, big jam, you can call it whatever you want to call it.</p>
<p>Now after giving this junk pile in him.</p>
<p>The next thing to do is to outline the stages of our workflow here in peach jam.</p>
<p>So let's do that.</p>
<p>So first things first out, zoom into 200% outcome here to zoom in and out Select Zoom to 200% here.</p>
<p>And when I zoom in to 200% out, use a square shape here to write down a headline for our workflow.</p>
<p>So I would keep this there, I would select the text to now so that I can write my text.</p>
<p>And I would say, workflow stages, then outcome here, and I'll align the text to the left.</p>
<p>And I'll change the color of the rectangle to this.</p>
<p>And that.</p>
<p>Okay, so the next thing I'll do is to have sticky notes, were out outline the workflow stages in.</p>
<p>So to create a sticky notes in peach jam, I would come here and now select the sticky note tool here.</p>
<p>When I select it out, come here and out, click on the big jam Canvas to have this.</p>
<p>Now let's select this.</p>
<p>And let's expand the width to align with our sticky notes.</p>
<p>So first things first, I will change the color of my sticky notes to this, then I'll click on this Add text placeholder here.</p>
<p>So that I can write down all of those workflow stages that I talked about.</p>
<p>So I would like to make this a list.</p>
<p>And I'd like it to be a bulleted list.</p>
<p>So I would come here and I would select the bulleted list property here.</p>
<p>Then I would write down the first workflow stage, which is this, it says stakeholders present the problem and the users facing the problem.</p>
<p>Now I'll create another list item, which is going to be the next stage of our workflow.</p>
<p>And that's going to be where the stakeholders will define the goals for this project.</p>
<p>So I would say define goals.</p>
<p>Let's come here.</p>
<p>Let's create some space here.</p>
<p>Now let's outline the next stage of our workflow.</p>
<p>After the goals are defined, we view X designers will empathize with the users.</p>
<p>So let's come here.</p>
<p>Let's create the space also.</p>
<p>Now After we the UX designers empathize with the users, the next stage of our workflow will be where we are going to create a problem statement.</p>
<p>So I would say, creates problem statements.</p>
<p>So let's come here, let's create the space.</p>
<p>Now after we create a problem statements, the next stage of our workflow will be the stage, where we are going to come up with an idea that can solve the problems listed in the problem statement.</p>
<p>Now, after we come up with a best idea that can solve the problems in the problem statement, the next stage of our workflow will be the stage where we are going to design that idea into a testable prototype.</p>
<p>So I would say design prototype here.</p>
<p>And after we design that idea into a testable prototype, we are going to move over to the next stage of our workflow, which is going to be the stage where we are going to test that idea that we have designed into a prototype.</p>
<p>So I would just call that test and have that spaced.</p>
<p>Now we have outlined our workflow stages here.</p>
<p>So just to make this better, I would select all of these and I would make all of the text bold.</p>
<p>To have that outcome here, I would select this text, and I'll make it bold also.</p>
<p>Now zoom back to 100%.</p>
<p>To see what we have, and this is okay, so I'll use the hand tool, which is this, you can come here to click on it to select it or just press the H key on your keyboard to have it selected.</p>
<p>And now grab and shift a canvas to this point.</p>
<p>So now we have outlined our workflow stages here right.</p>
<p>Now the next thing to do is for AWS to outline all of the actions that will be taken on that each of this workflow stage.</p>
<p>So this means that we are now going to break down each of these stage one after another, so that we know what actions to take at each of these stage and how to optimize for our results.</p>
<p>So I would select the Move tool here by clicking on it or by pressing the V key on my keyboard to select it.</p>
<p>And I would come here, I would select the square tool there so that I can create this shape like this.</p>
<p>And over here, I would write a text inside this shape.</p>
<p>And that text will be this first stage out select all of this text here, then I'll use CTRL.</p>
<p>C, if you are using a Mac, its command C, I would use that to copy that text.</p>
<p>And I'll paste it inside this question like this.</p>
<p>Now expand this to this point.</p>
<p>Now this is the first stage of our workflow right outcome here now.</p>
<p>And I'd have a sticky note here, right under that.</p>
<p>Now in this sticky note out write out what's going to happen at this stage, which is the first stage of our workflow.</p>
<p>Now this stage is the stage where the stakeholders will present the problem to us.</p>
<p>And also let us know about the users that they want us to design for.</p>
<p>So in this course, I would like us to assume that we have a stakeholder somewhere or we have a company somewhere that wants us to design an app that you can use to invest in stocks for them, right.</p>
<p>So I'll paste this in here in this sticky note, which says users find it really hard to invest in stocks using existing investment apps due to information overload and complex presentation of information on the apps.</p>
<p>Now, who are the users, the users are stock investors in Nigeria.</p>
<p>So this so having this here means that the stakeholders have presented us with a problem and the users facing the problem.</p>
<p>So this is sorted.</p>
<p>So let's change the color of the sticky notes.</p>
<p>Something like this to differentiate it from this one here.</p>
<p>And let's come here.</p>
<p>Let's change this, to that to differentiate it also.</p>
<p>So this is the first stage of our workflow.</p>
<p>And we have seen what's going to happen here at this stage.</p>
<p>So let's look at the next stage here, which is the stage where the stakeholders will define the goals of the project.</p>
<p>So I would come here, I would select this and now duplicate it to duplicate is Ctrl D.</p>
<p>If you are using a Mac, its command D.</p>
<p>So I'll duplicate this and our habits to here.</p>
<p>I will take out this text inside this shape.</p>
<p>And out writes define goals there.</p>
<p>I can have in brackets saved by stakeholders.</p>
<p>So I'll keep this here.</p>
<p>Now outcome here also out duplicates these and out habits, they're right on the dish shape, which is a square shape, right.</p>
<p>So inside the sticky notes, I'll take all of these out and out.</p>
<p>also assume that we have stakeholders somewhere who sent us the goals.</p>
<p>That's the ones for this project.</p>
<p>So let's assume that the stakeholders sent us this as their goal.</p>
<p>And it says, research and help us us simplify every task needed to make a stock investment.</p>
<p>So what we have here so far is this, the stakeholders have presented us with a problem and B users facing the problem.</p>
<p>And they have gone ahead to define their expected goal for this project.</p>
<p>And the expected goal is that they want us to research and help users simplify every task needed to make a stock investment.</p>
<p>So let's move over to the next stage of our workflow, which is the stage where we the UX designers will have to empathize with the users facing the problem.</p>
<p>So I would come here, I'll duplicate this, I would have this here.</p>
<p>And I would say empathize.</p>
<p>Now I have this here also.</p>
<p>And I'll take out all we have here.</p>
<p>And at this empathize stage, this is actually the stage where we the UX designers will now get to work.</p>
<p>So what do we do at this stage? What are the actions that we need to carry out at this stage, so that we can say that we have properly empathized with the users facing the problem.</p>
<p>So what we are going to do is to interview the users face to face or send out surveys digitally to the users.</p>
<p>The purpose for that is so that we can understand the problems from the perspective of the people facing the problem.</p>
<p>Now after that, we are going to create what we call user personas, all under this empathize stage.</p>
<p>So out, make this a list, just like this, to have that organized properly.</p>
<p>And when we are done with the empathize stage, by carrying out these two actions here, the next thing we are going to do is to move over to the next stage of our workflow, which is the stage where we will have to create a problem statements.</p>
<p>So I would come here, I would have this here.</p>
<p>And I'll change that to create problems statements, and have this stay here.</p>
<p>So at this stage, where you the UX designer will be needed to create a problem statements, what you do to create a problem statements, it's easy, just state the problem of the users with all you have gathered from the previous stage, which is the empathize stage.</p>
<p>So after you have interviewed the users to understand the problems from their perspective, and you have created user personas for each of the user, what you do is you'd use all of that data to properly state the problem that the users are facing.</p>
<p>Now when you create the problem statement, which is you stating the problem properly, the next thing you do is to move to the next stage of our workflow, which is the idea stage.</p>
<p>Now, when you get to the idea stage, let's have this here.</p>
<p>When we get to the idea stage, the actions that you take at the idea stage are simple actions.</p>
<p>All you'd have to do with this, launch a brainstorming session, then during the brainstorming session, vote for the best idea, when you vote for the best idea, select the idea with the highest votes.</p>
<p>And there you have gotten an idea that you can then take to the next stage of our workflow, which is the stage where we are going to design that best idea into a testable prototype.</p>
<p>So before we go there, let's select this and let's make it a list like this.</p>
<p>Now, let's come here and let's look at the next stage here, which is the design prototype stage.</p>
<p>And when you get to this stage, what are the actions that you need to take for you to properly design a workable prototype, we are going to look at the actions now.</p>
<p>So out have this the here I'll take all of these out.</p>
<p>And the actions that we are going to take to properly design a prototype are all of this.</p>
<p>First things first, we are going to create an information architecture for the best idea that we got from the idea stage.</p>
<p>When we create that in commission architecture, we are going to use that information architecture to create what we call a low fidelity prototype.</p>
<p>Now, after we create that low fidelity prototype, we are going to test the low fidelity prototype.</p>
<p>And when the test is successful, we are going to go ahead to create a high fidelity prototype for that best idea that we got from the idea stage.</p>
<p>Now, after we create the high fidelity prototype, we are going to move over to the next stage of our workflow, which is the stage where we are going to need to test that high fidelity prototype.</p>
<p>So I would come here, I'd have this here, I would say test prototype.</p>
<p>And I'll bring this here, I can just say usability testing here.</p>
<p>And that's all.</p>
<p>Let's come here, let's make all of these illest.</p>
<p>And that's okay.</p>
<p>So what we have here is a proper breakdown of our workflow.</p>
<p>So I like to connect all of this so that we understand that these stages are to be followed one after another.</p>
<p>So I would select the connector tool here, you can see where my mouse cursor is on, click on it to select it, I would come here out, select this point, click hold and drag.</p>
<p>And I would connect with this other point here, I would select this also connected here.</p>
<p>I'll do that for all of these other items.</p>
<p>Also, I would have all of them connected.</p>
<p>So we are going to design our products by following the breakdown of this workflow.</p>
<p>So now that we have outlined our workflow stages, and we have broken down all of our workflow stages like this, the next thing we need to do is to start executing each of the actions that we have outlined here, one after another.</p>
<p>So let's get to work.</p>
<p>So the first stage of our workflow here is the stage where the stakeholders will present us with the problem and the user space in the problem, right.</p>
<p>And as you can see, that stage is sorted, because I assumed that a stakeholder presented us with this problem and the users facing the problem.</p>
<p>So this stage is sorted.</p>
<p>Now over to the next stage, which is the stage where the stakeholders will state their expected goals for the project.</p>
<p>And that is sorted also, as you can see here, I also assumed that the stakeholders has stated the expected goals to us, which is to research and help us simplify every task needed to make a stock investment.</p>
<p>Now over to the next stage, which is the stage where we the UX designers will get to work.</p>
<p>And that is the empathize stage.</p>
<p>And under the empathize stage here, these are the actions that we need to take.</p>
<p>The first action is to interview the users face to face, or send out surveys digitally to the users.</p>
<p>Now in this course, since this is a lesson, I can't show you how to set up a face to face interview.</p>
<p>But I'll show you how to create a digital survey using Google Forms.</p>
<p>So let's do that.</p>
<p>So I would come here in my browser, and I would open a new tab, then come here, I would click on this menu icon here so that I can access my Google Apps out scroll down and out, click on forms here.</p>
<p>And when I do that, I would come here and I would click on Blank there, then a blank form will be created for me.</p>
<p>Now I'll give this form a title.</p>
<p>I can call it stock app UX survey.</p>
<p>And that's its outcome here also, and I'll give the form a name.</p>
<p>So I can call the form stock up UX survey also, or you can give it any name at all that you want to give it.</p>
<p>Now the next thing I would need to do is to have a form description just to describe what the survey form is all about.</p>
<p>So outcome here, and I'll have this and it says this survey is carried out by best technologists.</p>
<p>And it is aimed at improving the experience of users who want to invest in stocks from an app without having complex steps.</p>
<p>Now you can come up with a better description when you are doing this in real life.</p>
<p>Now after that out, start passing in the fields that I want the users to give me a response to, and the first field out have here will be an email field.</p>
<p>I'd like to collect the email address of everyone that will take part in the survey.</p>
<p>So that's going to be my first field here.</p>
<p>So to collect email addresses outcome here.</p>
<p>I'll click on settings here.</p>
<p>Then I'll expand responses here.</p>
<p>You can see the responses section here, I'll expand it.</p>
<p>Then in front of this collect email addresses option here, I'll turn on this toggle button, just like that.</p>
<p>And that's sorted.</p>
<p>Now when I come back here, you will see that we have an email field here, which is going to require the user to enter their email address here.</p>
<p>And as you can see, there is a red Asterix there, showing that this is a mandatory field, which means that anyone taking this survey must have to enter their email address.</p>
<p>Now let's move over to the next question that we are going to ask anyone taking the survey? And that's going to be us asking them to enter their full name.</p>
<p>Yeah.</p>
<p>So I would come here, when I type that in, I would change this from multiple choice to shut answer just like that, then I would come here and I would turn on this toggle button to make this field a required field, meaning that anyone taking this survey must have to enter their full name.</p>
<p>And that's sorted.</p>
<p>So I would come here and I would click on the plus sign here to add another question.</p>
<p>Just like that, then this question will be country of residence.</p>
<p>Now, this is important, because coming from what the stakeholders presented us as a problem and the user space in the problem, we could see that the stakeholders are actually trying to solve a problem for people living in Nigeria.</p>
<p>So it is important to ask anyone taking the survey from where they reside.</p>
<p>So if someone from Germany takes the survey, by mistake or happenstance, then it means that when we are collecting the data from the survey, we are actually going to ignore that person's imputes.</p>
<p>Because the person is not based in Nigeria.</p>
<p>So that's why it's going to be important to ask this question.</p>
<p>So I would come here and I would make this required also.</p>
<p>Now make sure this is set to short answer also, then I would come here and I would click on this button to add another question.</p>
<p>Now this question is going to be us asking anyone to can be surveyed enter their age.</p>
<p>And this is also important, because usage of apps, and the experience behind the usage of apps differs by age range.</p>
<p>So I would ask this question, and I would set this to short answer, then I would make this a required question.</p>
<p>So I would go ahead and add another question option here.</p>
<p>So that I can ask my next question, which is going to be us asking whoever is taking the survey to enter their profession? I would keep this short answer.</p>
<p>And I'll make this required.</p>
<p>Then I'll add another question here.</p>
<p>And this question is going to be us asking, have you invested in stocks from a mobile app? Now this is going to be a yes or no answer.</p>
<p>And Google Forms automatically suggest this because I have a question mark at the end of the question.</p>
<p>Now outcome here, and I'll click on yes as my first option.</p>
<p>And I'll click on No as my second option, and that's going to be fine.</p>
<p>Then I'll come here and now make this is a required question.</p>
<p>Then I'll add another question here, which is going to be select the goals you always love to achieve when investing in stocks from a mobile app.</p>
<p>Now, I'll have that in brackets.</p>
<p>Same select more than one.</p>
<p>Now outcome here, and I'll make sure this is a checkbox option.</p>
<p>Now mimicking this checkbox option is because I want the person taking the survey to select more than one answer.</p>
<p>So I would come here, I'll type in my first option, which is going to be invest quickly.</p>
<p>My second option will be found my wallet with more than one option.</p>
<p>The third option will be withdraw my dividends quickly, the fourth option will be easily access transaction history.</p>
<p>And the final option here will be to save time.</p>
<p>So this is me asking anyone taking this survey to tell us what they would love to achieve more when using a mobile app to invest in stocks.</p>
<p>So these are all the options that they can choose from and from the answers they select.</p>
<p>We the UX designers will understand what to focus on when designing and what not to focus on when designing.</p>
<p>So I would come here and I would make this a required question also.</p>
<p>And that's fine.</p>
<p>And I'll add another question here.</p>
<p>Which is going to be me asking anyone taking this survey this question it says select the frustrations you face when investing with the app you are currently using to invest so out also good Give them the option to select more than one answer here.</p>
<p>And I'd have checkboxes selected here.</p>
<p>So the first option here will be complex and unnecessary graphs, the second one will be long time to invest.</p>
<p>And the third option will be excessive ambiguity of information.</p>
<p>The fourth option will be on friendly user interface.</p>
<p>And the final option will be difficulty in funding wallets or accounts.</p>
<p>Now, this is us asking whoever is taking the survey to tell us the problems that they have with any investment app that they're currently using.</p>
<p>Now from what they would select here, we the UX designers will understand the problems to tackle and what to completely avoid when designing our own investment up.</p>
<p>So outcome here and I would make this a required question also.</p>
<p>And the final question, or the final request out have in this survey is to have the person taking the survey to upload their picture.</p>
<p>Now, this is not going to be a mandatory field, we are going to make it optional if they like the upload if they like they don't.</p>
<p>So I would come here out, click on the plus sign that add question.</p>
<p>And I'd come here and select File Upload.</p>
<p>Now outcome here, and I'll click on Continue.</p>
<p>And I would come here and I'd say upload your image.</p>
<p>And I would make sure this is not set to required.</p>
<p>That's because I want it to be optional.</p>
<p>And that's fine.</p>
<p>So at this stage, I'd like for us to preview this survey to see how it will look like when it is sent out to the people facing the problem.</p>
<p>So I would come here, and I would click on this button here, you can see where my mouse cursor is on, when I click on it, I would have a preview of the survey.</p>
<p>And this is it here.</p>
<p>It looks okay.</p>
<p>So let's come back here.</p>
<p>And let's click on send.</p>
<p>When you click on Send, you'd have this pop up show up here.</p>
<p>Now you'd come here and you'd edit this message, just in case you want to send this as an email to whichever person you want to send it to.</p>
<p>So you would come here and you'd say, vest, technologies there, you put in your own company's name, best technologies, has invited you to fill in a survey for UX research, or whatever you want to say there.</p>
<p>And that's fine.</p>
<p>Now this option is only when you want to send this survey form an email directly to people, you would come here and you type in their email address.</p>
<p>Let's say you type this in, you would use comma then type in the next email and the next email and the next email.</p>
<p>Now, if you don't want to send this as an email, you have the option of sending this also adds a link.</p>
<p>Now this option will make it possible for you to put this link up on your social media or send it through WhatsApp or send it through any other app to the public so that anyone that stays in Nigeria can stumble upon the link and take the survey.</p>
<p>Now to do that, come here and click here.</p>
<p>When you click there, you'll see the link here.</p>
<p>Now come here and click on this checkbox that says shorten URL.</p>
<p>When you do that, you'd have a shorter link.</p>
<p>Now you'd come here and just copy this link.</p>
<p>When you copy it, then you can post it on LinkedIn, you can post it on Twitter, you can post it anywhere you want to post it, you can send it to anyone.</p>
<p>And when they click on the link, they will be taken to the survey form for them to take the survey.</p>
<p>Now when they take the survey, you will be having the option to see the responses here.</p>
<p>All you do is come back to the form, click on responses and you'd see all of the responses over here.</p>
<p>Currently, I have zero responses.</p>
<p>So what's going to happen is out take this survey myself, I would take it twice, so that I would have two responses.</p>
<p>And I'll use those two responses to continue our research process.</p>
<p>Now take note in real life, you'd have more than two responses.</p>
<p>So I'll pause this video here.</p>
<p>I would go ahead and out.</p>
<p>Take the survey myself twice.</p>
<p>So I have taken the survey by myself twice.</p>
<p>And these are my responses.</p>
<p>As you can see here we have this field that says who has responded and these are the emails of the people that have responded and these are their full names and all of that now, this summary tab here in the responses section will just give you a full summary of all the responses.</p>
<p>Now for you to attend to one response at a time, come here and click on the individual tab appear.</p>
<p>When you do that, then you can come here and select the individual responses based on their email addresses.</p>
<p>Currently, this email is and@xyz.com.</p>
<p>And, and all of these responses here, all of these answers are the answers of this particular user.</p>
<p>If you want to see the answer from any other user, come here and select that with the email of that user.</p>
<p>If I select chicks@xyz.com, you will see that I would have all of this show up here.</p>
<p>Now, as you can see here, this is the email of chooks.</p>
<p>And this is the full name of trucks, trucks, EK, and the country and city of residence is Nigeria, Enugu, the age is 24.</p>
<p>The profession is importer.</p>
<p>Have you invested in stocks? Yes.</p>
<p>Have you invested in stocks from a mobile app? Yes.</p>
<p>Select the goals you always love to achieve when investing in stocks from a mobile app.</p>
<p>And Chuck said to invest quickly to one my wallet with more than one option to easily access transaction history and to save time.</p>
<p>Now, the next question here is select the frustrations you face when investing with the app you are currently using to invest.</p>
<p>And chucks says, long time to invest complex and unnecessary graphs, excessive ambiguity of information and non friendly user interface.</p>
<p>Now, for the other user, which is n, you can see the email of the user here and the name of the user is M for lucky.</p>
<p>And the country and city of residence is Nigeria Lagos.</p>
<p>I know in my initial survey form, I did not include city of residence, actually.</p>
<p>But I just had to include that so that I can target the particular location where the user is staying.</p>
<p>And the age is 24.</p>
<p>The professional is mural artist.</p>
<p>Have you invested in stocks? Yes.</p>
<p>Have you invested in stocks from a mobile app? Yes, select the goals you always love to achieve when investing in stocks from a mobile app and MCs to invest quickly to find my wallet with more than one option is the access transaction history save time and for this question here and select long time to invest complex and unnecessary graphs, excessive ambiguity of information and non friendly user interface.</p>
<p>Now at the bottom here, you would also see that the date of submission and the time of submission is recorded.</p>
<p>So I'll come back here.</p>
<p>And I'd also like to let you know that you can, you can export this response to a spreadsheet.</p>
<p>Now, I would advise you that if you want to do that, come here, click on summary, then click on create spreadsheets.</p>
<p>When you do that, you'd have this option to select, create a new spreadsheet or select existing spreadsheets.</p>
<p>Now, if this is your first time, just create a new spreadsheet.</p>
<p>Now I'll keep that now out, keep that selected, come here and out, click on Create.</p>
<p>When I do that, I'll have a new tab launched.</p>
<p>And as you can see, all of my responses has been exported into the spreadsheets.</p>
<p>Now you can also choose to come here and make your analysis from the spreadsheets.</p>
<p>And that's okay.</p>
<p>So after you create your surveys and send them out and the users or the people that you sent them out to send in their responses, you would go ahead to create what we call user personas for each and every user that sent in a response.</p>
<p>So at this stage, I'd like us to see how to create user personas and take notes.</p>
<p>Creating user personas is an action you take while you're at the empathize stage.</p>
<p>Now just understand that this empathize stage is the stage where you get to know the users better and understand their frustrations better.</p>
<p>And that's because it's only when you understand a problem better that you can come up with a better solution for that problem.</p>
<p>So let's go ahead and let's see how to create user personas for each of the user that sent in a response to our survey.</p>
<p>So I would come here now.</p>
<p>And I would select the text tool here.</p>
<p>And I'd have this here, I would say user personas, I would keep that selected.</p>
<p>I'll change this text from a normal text to a sub heading text.</p>
<p>And I'd make this bold, then I would come here and I'll change the color of this text to that.</p>
<p>So this is going to be our user persona section.</p>
<p>Let's duplicate this.</p>
<p>Let's come up here.</p>
<p>Let's call this section, workflow break down.</p>
<p>However you want to call it, it's fine.</p>
<p>That's okay.</p>
<p>So I'll just scroll down to the user persona section.</p>
<p>And the first thing I'd have here is the image of the user that I want to create a persona for.</p>
<p>So I would come here, I would select the square tool here to have a square shape here, which I am going to use to place the image of that user in.</p>
<p>Now this is necessary, whether the user sends in an image or not, you can just have these here, if the user does not send in an image, then you leave this blank, go ahead and do the rest.</p>
<p>But if the user sends in an image, then you place the image in here.</p>
<p>Now there's one way to place an image into a shape here in feature, all you have to do is keep the shape selected, right click on it, then go to plugins and use the Unsplash plugins for that.</p>
<p>So I would come here, I would launch that plugin.</p>
<p>And I would come in here and I'll type in African woman.</p>
<p>So I can have an image of an African woman show up there.</p>
<p>So I'd come here and out select this.</p>
<p>And that's okay.</p>
<p>So the next thing to do is to have all of these details about this person who has this image.</p>
<p>Now the name here is an felucca, the country and city is Nigeria, Lagos the age is 24 Professional mural artists.</p>
<p>Now, over here, I would say an is a mural artist resident in Lagos, Nigeria, and is also a stock investor who invests in stocks with existing stock investing apps in Nigeria.</p>
<p>And this is like his summary about her personality.</p>
<p>Now, I'll go ahead and out highlight her frustrations with the existing investment apps that she used in Nigeria and out also highlights the goals that she aims to achieve with an investment app.</p>
<p>So outcome here, now have this here, outpaced this.</p>
<p>And over here, these are the things that she wishes that she had as an experience with an investment app.</p>
<p>And these are her current frustrations.</p>
<p>Now all of these details about an was gotten from the response that she gave us when she took this survey that we created.</p>
<p>So you can see how this connects.</p>
<p>So let's go ahead and let's create a user persona for the other user that took the survey.</p>
<p>So that is going to be chooks.</p>
<p>So I would come here, I would have this shape here.</p>
<p>And I would run the Unsplash plugin on that shape.</p>
<p>And I would type in African man.</p>
<p>And I would go with this here.</p>
<p>And that's okay.</p>
<p>So I would have this hair for chooks.</p>
<p>This is his name, and his country and city, age, profession, and all of that out also highlight his goals and frustrations.</p>
<p>And that's fine still.</p>
<p>So what we have done so far is this, we have concluded the empathize stage, we have gotten to know about the problem from the perspective of the users.</p>
<p>And we have created user personas for each user that took our survey.</p>
<p>So we are going to move ahead to the next stage of our workflow here, which is the stage where we are going to create a problem statement based on all we have gathered during the empathize stage.</p>
<p>Now this really makes sense because you can create a better problem statement when you understand the problem better.</p>
<p>And the way to understand the problem better is to empathize with the people facing the problem.</p>
<p>And that's what we have done.</p>
<p>So let's go ahead and let's create a problem statement based on what we have learned.</p>
<p>So I'll duplicate this outcome here, I'd say problem statements.</p>
<p>And for me going by all we have learned from the empathize stage, this is my problem statement.</p>
<p>My problem statement states that users are frustrated with existing investment apps, as a result of excessive ambiguity of information and complex steps.</p>
<p>These consents negatively affect the experience of these users.</p>
<p>Now, this is my problem statements and this is the problem that our try solve.</p>
<p>So, if we come up here, you will see that we have empathized with the users and we have created a problem statement.</p>
<p>So the next stage of our workflow is the idea stage, which is the stage where we have to come up with an idea that can solve the problems that we have in the problem statement and what actions are we to take at this stage.</p>
<p>So at the idea stage, the first thing we are going to do is to set up a brainstorming session where we are going to invite other designers, product managers, business managers Lawyers, software engineers, and so on and so forth.</p>
<p>Now, when we invite all of these people, we are going to present them with enough information about the problems in the problem statement, and ask them to come up with ideas that can possibly solve the problems in the problem statement.</p>
<p>Now, when each and every one of these people that we have invited, come up with an idea, the next thing to do is to read out all of these ideas to everyone and call a vote for the best idea.</p>
<p>Now, the idea with the highest votes should be selected.</p>
<p>And when that is done, it means that you are ready to move to the next stage of our workflow, which is the stage where you'd have to design that idea into a testable prototype.</p>
<p>So before we move over to this stage here, I'd like to come here out also highlights that this stage is the idea stage.</p>
<p>This is the idea stage.</p>
<p>And since this is going to be a brainstorming session stage, and obviously I can't have a brainstorming session here in this lesson, it's going to be something that you'd set up with the people you want to set it up with, beat on Zoom discord, beat real life, anyhow, you want to set it up, that's fine.</p>
<p>So I'll just highlight this stage here.</p>
<p>And what I'm going to do is, I would assume that I conducted a brainstorming session offline, just so that we can learn better.</p>
<p>And I'd also assume that during that brainstorming session, we arrived at an idea.</p>
<p>So I'd have this here selected idea.</p>
<p>And I would paste this as our selected idea.</p>
<p>Now this is the selected idea for this course, it says Create an investment app where graphs are represented with text, where users will have the option to fund the account and wallet via bank transfer or their debit cards, where recent transaction history will be easily accessible.</p>
<p>And were plain and easy to understand English will be mostly used.</p>
<p>Now if you look at this idea, you'd see that this idea solves the problems that we have in this problem statements.</p>
<p>And this problem statement was gotten from all we learned during the empathize stage.</p>
<p>And we were able to learn all we learned during this stage because we created a survey form and sent out the survey to use us so you can see how everything connects.</p>
<p>So now that we have an idea that we can use to solve the problem, the next stage here is the design prototype stage.</p>
<p>And at this stage, the actions that we need to take all of these First things first, we need to create an information architecture for this best idea that was selected during the idea stage.</p>
<p>So I would come here, I would scroll down to this point.</p>
<p>And I would have this here, I'd say information architecture.</p>
<p>Now before we create the information architecture, let's understand what an information architecture is and why it is important to create one.</p>
<p>So the information architecture of a mobile app is the way you organize and arrange information on the mobile app that will help the users have that mobile app to accomplish their task on that mobile app without a bad experience.</p>
<p>So it is in the information architecture, that you will decide what features and what information we exist on each page of the app, and each step of the app.</p>
<p>So let's go ahead.</p>
<p>And let's create an information architecture for this idea.</p>
<p>Now, the way to start creating your information architecture is to first of all, define the goals of the users who will use the app, then define the task that the users have to complete to achieve their goals on the app.</p>
<p>So outcome here, and I'd have this here.</p>
<p>So this here is the goal of the user to invest with a good experience.</p>
<p>Now the user task here are the actions that the user will have to take to achieve this goal.</p>
<p>Now, what are the task, the user will have to sign up to the application as a new user or log in as an existing user then fund their account or their wallet, then use the fund that they have in their account or wallet to invest in any stock of their choice.</p>
<p>So if they can accomplish this task, this task and this task, it means that they have achieved that goal on that app.</p>
<p>So after defining the goals of the user and stating the task that the user has to complete to achieve that goal, we are going to go ahead to create our information architecture flow, and for the sake of time out, speed up this process, and I'll explain it so that you can understand.</p>
<p>So what we have here is our information architecture flow.</p>
<p>And our zoom in so that I can break down this flow one after another and also show you how to come up with a flow like this.</p>
<p>This is the start point of the flow.</p>
<p>This is where the user launches the app.</p>
<p>So when the user launches the app, the user will have two options, one to sign up and want to log in.</p>
<p>So let's go with the signup flow here.</p>
<p>Now, if the user is trying to sign up, the user will be required to sign up with their email address, phone number and password.</p>
<p>And after this step, the user will have to verify their phone number.</p>
<p>Now, after the phone number is verified, the user will be taken to the homepage of the application.</p>
<p>When the user gets to the homepage of the application, the user will have all of these options here.</p>
<p>And the first route or the first option here will be the menu icon, which will be on the homepage.</p>
<p>The user will also have the account balance displayed on the homepage, the user will have a fund account option that they can use to fund the account still on the homepage.</p>
<p>And still on the homepage.</p>
<p>The recent transactions by the user will be displayed there on the homepage.</p>
<p>Now, still, on the homepage, we are going to have a referral banner.</p>
<p>Still on the homepage, we are going to have an invest route that the users can take if they wish to invest in stocks.</p>
<p>Now still, on the homepage, we are going to have a transact option, just in case the user wishes to deposit or withdraw.</p>
<p>So all of this is on the homepage.</p>
<p>Now let's look at the flow of the first item here, which is the Menu icon.</p>
<p>Now if the user clicks on the menu icon, which is on the homepage, the user will see all of these options, recent transactions, card management, investment portfolio request statements and settings.</p>
<p>Now, just for the sake of those who don't know what a menu icon is, if you go to an app or a website, using your mobile phone, you would always have this icon here at the top that when you click on it, you'd have a drop down or you'd have a menu bar sliding from the left or from the right now, that's what we call the Menu icon.</p>
<p>And most mobile apps have that.</p>
<p>So this is going to be all that we show up when the user accesses the menu icon route now for the account balance, or that's going to show a base available balance.</p>
<p>And that's all.</p>
<p>Now for the fund accounts option.</p>
<p>This is the flow, the user will have to choose a method.</p>
<p>And this is important for the experience.</p>
<p>Because from our user research, it was clear to us that the users actually want an experience where they would have the option to fund their account with more than one option.</p>
<p>So when they choose a method, then they would go ahead to find the account with that method that they have chosen.</p>
<p>So that's what the fund accounts route right now for the recent transactions route.</p>
<p>All the user will have when they access a recent transaction will be the transaction details.</p>
<p>And that's okay.</p>
<p>Now we have the referral banner option here.</p>
<p>And when the user access the routes, they would have a referral promo code that they can copy you know and send to a friend to join the app for all of that and all of that.</p>
<p>And that's fine.</p>
<p>Now we have the InVEST route here.</p>
<p>When a user accesses this route, the user will see a list of stocks that they can invest in and will also see their stock portfolio that they had invested in.</p>
<p>So if the user access one of the stocks that's been listed, the user will see the detail for that stock.</p>
<p>And if they like what they see in the detail, they will go ahead to invest.</p>
<p>And that's a good flow.</p>
<p>So if you come here, we have this route here, which is the transact route.</p>
<p>When the user accesses this route, the user will have the option to make a deposit, which is also like funding the account you get.</p>
<p>And the user will also have the option to make a withdrawal from the account.</p>
<p>So this is just the basic information architecture flow for this app.</p>
<p>And it is always important for you to create this information architecture, so that you will understand and organize the steps that the user will take on the app.</p>
<p>It is also important so that you can also streamline the core features that each page Your app will have.</p>
<p>Now if you remember, that was the signup proud, the login routes is still the same, because all you have to do here to login is just enter your email address and your password, then you'll be taken to the homepage.</p>
<p>Still, when you get to the homepage, every other theme is the same.</p>
<p>So that's that if you have any questions on the information architecture here, draw my attention to it.</p>
<p>And I'm there to help.</p>
<p>So if you come here now, in our flow breakdown, you'd see that under the design prototype stage, we have created our information architecture.</p>
<p>The next action at this stage is to create a low fidelity prototype of the best idea using the information architecture.</p>
<p>Now before we do that, I'd love to explain what a low fidelity prototype is.</p>
<p>So a low fidelity prototype is a dummy version of your final design for an app.</p>
<p>Now, the question you may ask is this, why do we need to design a dummy version? Now this is it.</p>
<p>Designing a dummy version is important because at this stage of trying to figure everything out, your design, and your design process can be subject to lots of changes, and imputes from the stakeholders.</p>
<p>Now, it's just like building a dummy house first, before you build the main house.</p>
<p>Now, if you use paper to build a dummy house first, before building the main house, it's going to be a lot easier when the owner of the house comes to make a correction or comes to make a change.</p>
<p>Since it's a paper, you don't have much to lose, all you have to do is just tear it and put it back in seconds.</p>
<p>But if you go ahead to build the main house first, and the owner of the house comes and says, Okay, I don't want this design here, I don't want that there, it means that you'd have to break down that part of the house and rebuild that part of the house with all of the resources that you have put into building that part of the house.</p>
<p>And that's going to be a lot more hectic compared to you using a paper to just build a prototype or a model of the house.</p>
<p>So that's basically what a low fidelity prototype is.</p>
<p>And that's why it is important for you to have a low fidelity prototype, then take that to the stakeholders for correction and changes and imputes and all of that.</p>
<p>Now, when the low fidelity prototype has been accepted and agreed on, then you can go ahead to design the real app itself, which is the high fidelity prototype.</p>
<p>So let's go ahead and let's see how to create a low fidelity prototype of our best idea.</p>
<p>So we are going to do that using a figma design file.</p>
<p>So I would come here, I would go to figma.</p>
<p>And I'll create a new design file.</p>
<p>And I'll call this stock investment app.</p>
<p>And out come here and out, rename the page one to low fidelity.</p>
<p>And this page is going to contain all our low fidelity screens.</p>
<p>So let's go ahead and let's start.</p>
<p>So to design low fidelity screens is easy.</p>
<p>And it is easy because you don't need a design system for that.</p>
<p>Like you don't need a style library.</p>
<p>To do that.</p>
<p>You don't need a component library.</p>
<p>To do that.</p>
<p>You don't need all of that, all you have to do is focus on the user task.</p>
<p>So if you come here, you'd see that our user task on this app is to sign up a login on your account or wallet and invest.</p>
<p>And if a user accomplish all of these tasks, it means that the user will achieve their goal on this app, which is to invest in stocks.</p>
<p>So we are going to design a low fidelity screams around these user task.</p>
<p>So let's come back here and I've picked my design file.</p>
<p>And let's see what it is to create low fidelity screams, all you have to do is select the frame tool, then go with any template of your choice, I would go with iPhone 13 Promax, and not have that.</p>
<p>So the next thing I'll do is to just come here.</p>
<p>And since this is going to be the splash screen, I'll just have this logo stay here out align it to the center, horizontally and to the center vertically, then I would go ahead to create the login screen, the signup screen and all of that.</p>
<p>And actually, the way I like doing it is this, I like to segment the screams into categories using the user task.</p>
<p>This section or this segment should be four authentication screens.</p>
<p>So I'll go ahead, speed up this process and have other screens here.</p>
<p>Then I'll explain how I came about all of that.</p>
<p>Now before I do that, I may have missed something here.</p>
<p>I know some people who are new to fit jam may not understand how these connectors are created.</p>
<p>Now all you have to do is use the connector to select it, click on the point, then you connect it anyhow, you want to connect it, you can take your connector anywhere, connect any shape that you are trying to connect, and that's fine.</p>
<p>And when your connector is created, you can actually play around with it, you can click on it to select it, grab the points, take it up, take it down, anyhow, you want to play around with it, it's fine.</p>
<p>Now you can also select the connector and change the color of the connector, just like this.</p>
<p>So all of these connection lines were created using the connector tool here.</p>
<p>So let's go back to our figma design file.</p>
<p>And out pause this video here and come back with all of our low fidelity screams, then I'll explain further.</p>
<p>So what we have here are low fidelity screens for the authentication task.</p>
<p>So let's zoom in.</p>
<p>As you can see, here, we have the splash screen, which is this.</p>
<p>Now after the splash screen, we have this screen where the user will have to choose that authentication action, which is either to login or to sign up.</p>
<p>Now to create this button here, you don't need to use an auto layout or any of that, all you just have to do is select the rectangle to like this created anyhow, you want to create it, then come here, select the text to and you can just say login or sign up or whatever you want to have.</p>
<p>They're just like this.</p>
<p>That's how I created this.</p>
<p>And I did not have to come up with a color.</p>
<p>And it's advisable for you not to use colors when creating your low fidelity screams.</p>
<p>And that's because if you have colors chosen, it may distract the stakeholders when you are presenting the low fidelity screams to them at this stage, all you should focus on is the user experience.</p>
<p>So having colors or making the low fidelity screams look good, may distract the stakeholders away from the user experience.</p>
<p>So that's how I came up with the buttons there.</p>
<p>And here also, this impute fields, I just use the rectangle, the rectangle to create a rectangle shape there, I added a stroke.</p>
<p>And I took out the field color and I had that then I had a text inside there saying email just like that.</p>
<p>And this button, we know how to do that.</p>
<p>I duplicated all of this.</p>
<p>And I had one more field here for the phone number.</p>
<p>And my button is still here.</p>
<p>Then here we have this field for a verification code.</p>
<p>And over here I have the Verify button that Okay, so all of the screens here are for the authentication task.</p>
<p>Now let's scroll down to the next task, which is going to be the fund wallets task.</p>
<p>And that task actually will happen from the homepage.</p>
<p>So that's why I created a low fidelity version of our homepage.</p>
<p>So you can see that we don't have too much of information here.</p>
<p>So if I scroll down, you'll see that I have the fund accounts pop up action here.</p>
<p>Now this element is going to show up when a user clicks on fund accounts here.</p>
<p>When they do that, this pop up will show up for them to choose the method that they want to fund the account with.</p>
<p>And that's okay, so this is easy to create, just have a rectangle like this and have your text inside of it.</p>
<p>Then the background of this navigation section is also a rectangle that I had across the screen like this, and I changed the color to something like this, just like that.</p>
<p>That's easy.</p>
<p>So over here, this is a rectangle also with a text on it.</p>
<p>And I have a rectangle here with a corner radius of 16 px.</p>
<p>And that's okay here, we know how to create a button.</p>
<p>And this is just text.</p>
<p>Now for this icon here, I got that from an icon plugin, I used the feather icons plugin to have that sorted.</p>
<p>So this task is complete, we have the font accounts button here, which if a user clicks on it, you will have this pop up show up like this.</p>
<p>Now let's move over to the next task on our app.</p>
<p>And the next task here is to invest.</p>
<p>So if I come here, and I scroll down, you'll see that I have this screens for the InVEST task.</p>
<p>Now this is the section for that we have this page here we have this icon we have this text here.</p>
<p>Now I have this section which is like the list of stocks to invest in.</p>
<p>I have this search bar here.</p>
<p>I have this search field here which is also easy to create.</p>
<p>All you have to do is create a rectangle give it a corner reduce of let's say 16 Or let's say 816 is a lot.</p>
<p>Then come here take out the the fill color and give it a stroke Hello, and you have that, then you have a text inside there, that's really easy to create, then I have the list of stocks here.</p>
<p>So I just have a rectangle here also with this text on top of it.</p>
<p>So it's also easy to create, all you have to do is just have something like this, then give it a canary use of 16, then take the color down the beats to this point, then have your text written on top of its plot away, then keep this here, then have this plus 234 percent.</p>
<p>They're all any number that you're okay with.</p>
<p>So that's how I created this.</p>
<p>And if you scroll down, you'll see that we have the your stock portfolio section, which has this also, we know how to create this.</p>
<p>And over here we have the navigation section.</p>
<p>And that's okay.</p>
<p>So the next page here, let's zoom out a bit.</p>
<p>The next page here is the stock Details page.</p>
<p>Now, this is all assuming that a user is interested in this stock here, you can see where my mouse cursor is on.</p>
<p>So if a user is interested in this stock, and the user goes ahead to click on it, this details page will show up for the stock showing the details of that stock and the company that owns the stock, you'd have the company logo here.</p>
<p>And you'd have the stock percentage and all of that there, you'd have the interest for that stock, minimum cap volume, about the company, the valuation rank and all of that, then you'd have an invest button here.</p>
<p>And I think by now we know how to create all of the elements here.</p>
<p>Now, if a user clicks on the InVEST button, they would go to this page where they would have to enter the amounts that they wish to invest in that stocks with.</p>
<p>And I believe on this page here, we know how to create all of the elements that we have here.</p>
<p>Now, if a user clicks on the next button here, after entering, the amount they wish to invest in that stocks with the user will be taken to the next page here, which is going to display the summary of the investments they're about to make.</p>
<p>Over here, they would have the amount that they typed in here, display here, the minimum cap, the interest value, and so many other details, and so many other details that are not listed here.</p>
<p>Now, if the user is okay with that, the user clicks on the Proceed button, and the next page that user will be taken to is the success page indicating that that investment is successful.</p>
<p>Now the user will have the option to click on the back to home button here.</p>
<p>And that's that it means that that task, which is the Invest task has been successful.</p>
<p>So for us to properly present low fidelity screens like this for testing and for impute and for opinions.</p>
<p>And for all of that.</p>
<p>For us to properly do that, it means that we need to make a prototype of this low fidelity screens, so that we can present them properly for testing and for imputes from the stakeholders.</p>
<p>So let's go ahead and let's do that.</p>
<p>I'll click on the prototype option here.</p>
<p>So let's start with the splash screen.</p>
<p>So out select out, click on the splash screen to select it.</p>
<p>When the splash screen is selected, you'd have this point here, all you have to do is click on it, hold it and drag it to the screen of destination.</p>
<p>So I would want the users to go from the splash screen to this screen here.</p>
<p>Now when I connect this splash screen to this other screen here, you'll see that figma will bring up this interaction details card for us.</p>
<p>So that we can set the mode of our interaction.</p>
<p>So over here I have the On Click event.</p>
<p>And the action for that onclick event is a navigate to action.</p>
<p>So what this means is that when the splash screen is clicked, we are going to navigate to this screen here, which is iPhone that in Promax two, this is the name here actually, you can actually it is advisable for you to rename all of your screens, that's the best way to do it.</p>
<p>So this practically means when the splash screen is clicked on, navigate to this other screen, which is this one here.</p>
<p>Now we have an animation section here that we can set the animation of that transition or the animation of that navigation.</p>
<p>So currently to set instance, I can come here and set this to smart animate, then set this to ease in and out and out.</p>
<p>Set the animation delay time to 800 milliseconds, just type in 800 there and press the Enter key on your keyboard and figma will add the milliseconds for you.</p>
<p>Now this animation settings is optional.</p>
<p>The most important thing here is that we have set the event and the action that will be triggered by that event, then we have sets to destination frame for that action.</p>
<p>And that's okay.</p>
<p>So that's sorted.</p>
<p>Now outcome here, out, click on this button.</p>
<p>And I will say, okay, when a user clicks on this login button, they should go to the login screen, which is this.</p>
<p>Now for the Interaction Details, ugly with set like this.</p>
<p>This is the setting we had before now.</p>
<p>So I'll leave it set like that.</p>
<p>Now, for the sign up button.</p>
<p>When a user clicks on the sign up button, it means the user is a new user.</p>
<p>So I would like that user to be taken to the signup page, which is this one here.</p>
<p>Now, when the user goes to the login page, and the user enters their email and their password, it means that they would have to click on the login button.</p>
<p>And when they click on the login button, I'd like them to go straight to the home page, which is this.</p>
<p>Now remember, for a user to log in, it means the user is an existing user.</p>
<p>Now, when a user selects the Sign Up option here, it means the user is a new user, and the user will have to enter their email address, phone number and password right.</p>
<p>Now when they do that, it means they would have to have their phone number verified first.</p>
<p>So when the user clicks on sign up, the user will be taken to the verification code page.</p>
<p>And when the user's phone number is verified, the user will then be taken to the homepage.</p>
<p>And that's fine.</p>
<p>So you have seen that we have created the authentication flow.</p>
<p>So let's come over here on the homepage, let's work on the next task.</p>
<p>Now the next task is to fund the accounts, right.</p>
<p>And to fund the accounts, the user will have to click on the fund accounts button.</p>
<p>Now when they do that, we are going to want a pop up to show up on the screen.</p>
<p>And that pop up should show this card here that will that will require the user to choose the method that they want to fund their accounts with.</p>
<p>Let's come here in our Interaction Details.</p>
<p>Over here, it's an On Click event.</p>
<p>That's okay.</p>
<p>Now, over here, we have the Navigate to option.</p>
<p>And that's not what we want, we want a popup to show up on that same screen, we don't want the user to leave that page that the user is on, we want the user to still stay on that page, but have a pop up show up.</p>
<p>So how do we make that happen, we are going to change this from navigates to to open overlay.</p>
<p>When we change it to open overlay, we are going to come here and select the center option, because I would want this pop up to stay at the center of the screen here.</p>
<p>So over here, I would keep this selected, which is closed when clicking outside and out.</p>
<p>Also keep this add background behind overlay options selected, then for the opacity of the background overlay out, keep it set to 25%.</p>
<p>Now for the animation, you can still keep it set instance or come here and select any other option of your choice.</p>
<p>So that's okay.</p>
<p>And we are okay with that.</p>
<p>Now, if a user selects bank transfer or debit card, they will be taken to another page where they would have to process that transaction method.</p>
<p>So you can also come here, if you don't mind, let's click on Design, you can come here and duplicate this page and and create a low fidelity screen for that you can call these bank transfer.</p>
<p>And you can have whichever element you want to have here.</p>
<p>And you can go ahead to have the debit card page also that the user will go to when they select the debit card option here.</p>
<p>But that's not the point here.</p>
<p>So I'll take this out.</p>
<p>Now we are done with the fund wallet task.</p>
<p>So the next task is the Invest task.</p>
<p>And this task will happen from the homepage.</p>
<p>It is when the users go to the homepage, that they would click on this invest option here for them to go to the InVEST page so that they can invest in stocks.</p>
<p>So from this homepage here, outcome held click on prototype.</p>
<p>From this homepage here, I would select this invest button here.</p>
<p>And I'll create a connection to this page.</p>
<p>And that's okay.</p>
<p>So when a user clicks on that invest button at the navigation section there on the homepage, that user will be taken to this page here, which is the Invest page where the user will see the list of stocks that they can invest in and their stock portfolio.</p>
<p>So if a user comes to this invest page, the task we want them to complete is to invest So let's say the user is cool with this stock here and the user wishes to invest in this stock, I would select it, then I would create a connection like this.</p>
<p>This means that when the user clicks on this stock, the user will go to the stock details page for that stock.</p>
<p>And when the user is okay with that stock details that the user sees here, the user will click on the InVEST button here.</p>
<p>And the user will go here to this other page, where the user will have to enter the amount that they wish to invest in that stocks with.</p>
<p>And when the user enters the amount they wish to invest with, the user will click on the Next button, which will take the user to this page here where the user will see a summary of the investment the user is about to make.</p>
<p>And when the user is okay with all the user sees here, the user will click on proceed and the investment, which is the task will be completed.</p>
<p>So what we have here is we are done creating a low fidelity screens.</p>
<p>And we can present a low fidelity screens for testing now.</p>
<p>So how do we do that, I would come here, I would select the splash screen, because that's where the whole journey starts from right? When I select it, I would come here, and I would click on this presents button here to have that presented, a new tab will be launched for that.</p>
<p>So I would come here, and I would click on the Enter full screen option here you can see where my mouse cursor is on.</p>
<p>Now, this is the presentation, I would present to the stakeholders, which are my employers or the owners of the app.</p>
<p>So I will take this presentation to them to demonstrate the user experience that I have come up with that will enable the users to accomplish their task on this app.</p>
<p>So I would go from here, I would click on this screen.</p>
<p>And I'll explain to the stakeholders at this point that existing users can click on login.</p>
<p>And new users can click on sign up.</p>
<p>So I would demonstrate these as a new user, I would say okay, when they click on sign up, they would come here enter their email, phone number and password.</p>
<p>When they click on the Sign up button, they would have to enter a verification code.</p>
<p>And when they are verified, they would go to the homepage.</p>
<p>Now, if they want to invest, it means they have to fund the account.</p>
<p>So I would click on the fund account button to demonstrate to them that in this case, now we have a bank transfer method and debit card method, I would say okay, if the users go ahead to fund to fund the accounts, then it means the users are ready to invest.</p>
<p>So for them to invest, they would come down here and click on the InVEST button there.</p>
<p>When we use that those that the user will see list of stocks that they can invest in.</p>
<p>And if the user chooses to invest in any of the stock, let's use this, for example, they would click on it, when they click on it, the user will be taken to the stock details page for that stock.</p>
<p>And when the user is satisfied with the details of the stock, the user will click on the InVEST button here, then the user will be required to enter the amount they wish to invest in that stocks with when the user does that, the user will click on the Next button here.</p>
<p>And when the user clicks on that next button, the user will see a summary of the investment they are about to make.</p>
<p>And if the user is satisfied, the user clicks on the Proceed button here and the investment will be successful.</p>
<p>And when the user is done, the user clicks on back to home, and the user will be taken back to the homepage.</p>
<p>So a presentation like this will really reveal the experience that the user will have using this product.</p>
<p>So if your low fidelity prototype has been accepted by the stakeholders, it means that it is now time for you to go ahead and start the process of designing your high fidelity prototype, which is going to be like the real design version of your app, or the final design version of your app.</p>
<p>And it is at that stage that you'd focus on themes like colors, typography, effects, components, library style library, and all of that.</p>
<p>So in this course, let's assume that our stakeholders gave us a pass for these low fidelity screams and they are okay with it.</p>
<p>Let's assume that our stakeholders now want us to go ahead to design the real version of the app.</p>
<p>So what do we do? Let's click on Design.</p>
<p>Come here.</p>
<p>Create a new page and call this Hi Fi deleting.</p>
<p>So at this stage, I'd like to welcome everyone to the most interesting part, which is the part where we start building our designs from scratch.</p>
<p>So first things first, I'll go ahead to create my style library.</p>
<p>And I will start by creating my typography styles.</p>
<p>So I will do that using the Material Design version to guide.</p>
<p>So I would come over here, I would go to material.io.</p>
<p>And when I come here out, click on Design.</p>
<p>When I click on Design out, come here on the left side, and I'll click on typography, then I would select the type system.</p>
<p>And when I do that, I would come here.</p>
<p>So the first thing that I would have set is the typeface or font family that I want to use for this project.</p>
<p>For this project, I would love to use the rubric font family.</p>
<p>So I would come here, and I would select it here for headlines and subtitles, then I would go ahead to select it here for body and captions, just like that.</p>
<p>Now I'll use the data here in this type scale to create my typography styles.</p>
<p>Now let's start with creating headline textiles for this project.</p>
<p>Now since this is a mobile app project, I won't see the need to have a headline one text, same for the headline to text.</p>
<p>So I would go with the headline for textile as my own headline one textile just because this is a mobile app design and this size of text is going to look too big for a mobile app.</p>
<p>So I would come here out click on headline for and I would use these details here.</p>
<p>So I would come here I'll create a frame here where my textiles are going to stay in so I would say headline one a duplicate this out say headline one bold.</p>
<p>So outloud say headline two now this is me getting everything set before I start applying the details that out get here from the type scale generator.</p>
<p>So outcome here out, duplicate this and out see headline to bold and out come here out have this out see a headline three.</p>
<p>And this is going to be headline three bold, and that's going to be that for my headline textiles for this project.</p>
<p>Now I'll go ahead to have my body textiles.</p>
<p>So I would come here out, prepare this for body large.</p>
<p>And I'd have this be a body large bold textile, then I would go with body small here.</p>
<p>And I'd have this as Bodhi small bald.</p>
<p>Now this is my own style.</p>
<p>And this is my own pattern.</p>
<p>I am not saying this is the standard out there.</p>
<p>I'm just doing this because this is what I feel will give me the best design.</p>
<p>Now come here.</p>
<p>This will be for my button text and I'll have a caption text.</p>
<p>So after having all of this set out, come here out select the headline one text here.</p>
<p>And I will use the headline for textile here in material design.</p>
<p>Just like I said I would use this for my headline one textile.</p>
<p>So the font family sets Rubik, the width is set to Normal, which is regular, the size is set to 35.</p>
<p>And the letter spacing is set to 0.25 px.</p>
<p>So I would go ahead and I would have all of these sets.</p>
<p>So I would come here keep this selected, how to set this to Rubik and how to set this to regular and for the letter spacing out come here and out set this to 0.25 px, and for the size out set it to 35 px.</p>
<p>Now I'll use these same settings for this headline one text for the headline, one bold text, the only difference will be that this is going to be a bold text and this is going to be a regular text.</p>
<p>So I would select this.</p>
<p>Now to set this to 35.</p>
<p>I would set this to beak and I'll keep it set to bold like I said, and I'll make this 0.25 px and that's okay, so I'll go ahead and now do same for headline to headline three body large body large bowed down to the caption text.</p>
<p>Now for the headline to text here, I would come here in material design and I would use the headline five textile for my own headline to textile.</p>
<p>So the font families Rubik, the weight is normal, the size is 24.</p>
<p>So I would set the size to 24.</p>
<p>And for the weights out, keep it set regular and for the font family.</p>
<p>I'll keep it set to Rubik.</p>
<p>Now the letters business zero px, so I can just keep it set at 0% or just come in here and type in zero px, and that's fine.</p>
<p>I would use the same setting for the headline to bold, but the difference will be that this is going to be a bold text So I would come here, I would set this to 24.</p>
<p>Send this to Rubik.</p>
<p>Keep this set to zero, keep the letter spacing set to zero, and then keep this sets bold.</p>
<p>So I can have that.</p>
<p>Now for my headline three text.</p>
<p>If I come here, I'll use the headline six textile here for my own headline pre text.</p>
<p>So I would keep this set Rubik, this set to medium size set to 20.</p>
<p>So I'll keep the size set to 20.</p>
<p>And for this, I'll keep it set to medium and outside this to Rubik.</p>
<p>Then for the letter spacing, it sets 0.15 px.</p>
<p>So I would come here, I would say 0.15 px.</p>
<p>And that's going to be cool.</p>
<p>Then for the headline three bold, I would have the same sentence there.</p>
<p>But the only difference as usual will be that this is going to be a bold text.</p>
<p>So I would come in here, outside this to rubik cube assets board.</p>
<p>And for the size, I think it's 20 px, and for the letter spacing is 0.15 px.</p>
<p>So I'll type that in.</p>
<p>And I'll keep this set to 20 Just like this.</p>
<p>And that's okay.</p>
<p>So for the body large text, come here and use the body one textile here, you can see that the size is 16 px, the width is normal, and the letter spacing is 0.5 px.</p>
<p>So I'd come here, keep this here, I would set the letter spacing to 0.5 px outsets, the weights to regular and outset these to 16.</p>
<p>And out set this to Rubik and that's okay, for the body large board, you know what to do already, how to set this to 16, set these to 0.5 px, set this to bold, then set this to Rubik.</p>
<p>And that's it.</p>
<p>So I'll go ahead and out, have my body small text here.</p>
<p>And if I come here and material design out, use the body to textile here material design for that.</p>
<p>So I'll keep it set to normal set the size to 14 and the letter spacing to 0.25 px.</p>
<p>So I would have this set to 0.25 px, I'd set this to 14, out set this to Rubik, and I'd set this to regular.</p>
<p>So I'd have this here.</p>
<p>And this is going to be 14 0.25.</p>
<p>And this is going to be Rubik.</p>
<p>And that's sorted.</p>
<p>Now for the button text.</p>
<p>I'll keep this here.</p>
<p>If you come here, you'd see that the button text here has a size of 14 px and a letter spacing value of 1.25 px with a weight that is set to medium.</p>
<p>Now, over here, material design to the button text is all in uppercase.</p>
<p>But in my case, I won't have my text stay in uppercase.</p>
<p>And I think in material design version three, the button text is not represented in uppercase.</p>
<p>So I would go ahead and I'd have this set of 14.</p>
<p>And the letter spacing is pretty big.</p>
<p>So I would have that set to 1.25 px.</p>
<p>And this will be set to medium with the font family sets to Rubik.</p>
<p>And that's what we have here.</p>
<p>Now for the caption text, it's going to be set to 12 px with a letter spacing value of zero points for PX and a normal weight.</p>
<p>So I would come here, I'll keep this here.</p>
<p>And now I have this sets regular, this will be 0.4 px.</p>
<p>And this will be set to 12 Just like this.</p>
<p>And the font family will be set Rubik.</p>
<p>So this is going to be a caption text.</p>
<p>So at this stage, what I'll do is I'll go ahead to save all of these styles that I have created to my style library.</p>
<p>And I think we all know how to do that by now.</p>
<p>So I would speed this process up, I would select this column here, and I would call this headline one out go ahead fast forward this part of the course and come back.</p>
<p>So this is it, I have created and saved the textile that I would need for this project.</p>
<p>So I would come here and I would rename this frame typography styles, just for better documentation, you know, now when I click on my empty canvas, you would see that I have all of my saved textiles over here.</p>
<p>Now let's go ahead and let's create a color styles out.</p>
<p>We'll name this frame to color styles.</p>
<p>I'd save that now out create my color styles based on my meat.</p>
<p>I want to make use of the Material Design Guide to create my color styles.</p>
<p>And that's because you can actually do that.</p>
<p>You can create your color styles your textiles you can create any of your styles without using the Material Design Guide And you can actually mix it, you can create your textiles with the Material Design Guide and have your color styles created from your own inspiration.</p>
<p>So outcome here, I'd like to have a background color here.</p>
<p>So I'll use this my background color, or have a text stay at the top here to indicate that this is for my background color, I would select this text and I would make use of one of my saved textiles.</p>
<p>So I'll go with the body large text there.</p>
<p>So for my background color style, I'd like to use this color.</p>
<p>And that's good.</p>
<p>Let's zoom into this point.</p>
<p>So we can see clearly, and after having a background color, I'll duplicate this use this here, I would love to have a surface color.</p>
<p>And for my surface color, I'd like it to be this color here, you can use any color of your choice, this is my own choice.</p>
<p>So I'll duplicate this, and have this day here.</p>
<p>And this time, I'd like to have a surface text column, you can call this an on surface color, actually.</p>
<p>So I'd like to have a surface text color, which is going to be the color that I'll use to write text on the surface color.</p>
<p>So I'd like this to be white.</p>
<p>Actually, I know this may not be visible.</p>
<p>But I'd like that to be whites just like that.</p>
<p>So I would duplicate this.</p>
<p>Now for us to make this visible out, select it and add a shadow effect.</p>
<p>The next color that out heavier, we called the off text column.</p>
<p>And that's my own choice, I'd like to have another color for my text.</p>
<p>So I would use this shade for my off text color.</p>
<p>And duplicate this.</p>
<p>And I'd have another color here, which is going to be my error column.</p>
<p>And obviously, this is going to be a red color.</p>
<p>So I'll use this shade of red for that, then I'd have this here.</p>
<p>And I'd like to have a second surface color.</p>
<p>And I'd like that color to be just like this.</p>
<p>And that's fine.</p>
<p>So I have selected all of the color styles that I would want for this project.</p>
<p>So I would go ahead and I would save all of these styles to my style library.</p>
<p>And I think we all know how to do that.</p>
<p>So I would select this column here.</p>
<p>And I'd call that background color, I would speed up this process and I would come back to it.</p>
<p>So as you can see, I am done creating and saving my color styles.</p>
<p>And these are my color styles here.</p>
<p>So that's sorted.</p>
<p>The next thing I'd like us to do is to go ahead and create the grid style that we are going to use for this project.</p>
<p>So to do that, I would use a mobile layout, I would use the iPhone pattern Promax layout, so I would have the iPhone 10 Promax layout here, I would rename it to mobile grid style out zooming to this point, I'll keep it selected, then I'll add a layout grid property to it, just like that, then I'd have this big column grid.</p>
<p>Now I have the count before I would have the margin be 16 out have the gotta be 16.</p>
<p>And for the color out go with something like this.</p>
<p>Now, we are sorted for the column grid.</p>
<p>So I would go ahead and add a row grid property to it.</p>
<p>I'll keep it selected still come here.</p>
<p>Now to add another grid property that outset, as a row grid property, just like this out, set the count to 800.</p>
<p>And out set the stretch to center out set the gutter property to zero out come here, I will set the height property to eight.</p>
<p>And that's because I want the space between the row lines to be eight px, then outcome here now change the color something like this.</p>
<p>And that's going to be okay for me.</p>
<p>So I would keep this selected.</p>
<p>Come here.</p>
<p>And I'll save this grid style as my grid style for this project.</p>
<p>So I'll click on style there.</p>
<p>And I'll call this mobile grid style.</p>
<p>You can call it whatever you want to call it.</p>
<p>Now we have three styles saved to our style library, we have our textiles, we have our color styles, and we have agreed styles.</p>
<p>So I would like for us to go ahead and create shadow styles for this project.</p>
<p>To do that, I would come here out have a frame here.</p>
<p>Then I would rename this to shadow styles, when I renamed that to shadow Stiles out have some rectangles right inside that frame.</p>
<p>And the rectangle is just to display the shadow effects and how it's going to look like.</p>
<p>So I'll keep that selected.</p>
<p>I'll make the corner radius to have a value of eight.</p>
<p>I'll give it this column.</p>
<p>And I'll duplicate this and have this here.</p>
<p>I'll just have three shadow effect styles.</p>
<p>So I'll keep that there and outcome here in material design.</p>
<p>Now, go to the homepage out, click on the Search icon there and I'll type in shadow.</p>
<p>When I press the enter key out, have these results show up.</p>
<p>So I would come here, I would click on this link here, that's going to take me to material design version one, bear out make use of the recommendations that they have there for creating shadow styles.</p>
<p>So I would click on that link.</p>
<p>Now come here, and I would use this shadow recommendations that's under the sketch section.</p>
<p>So I want to go with the one DP elevation table here, I'll scroll down, and I'll make use of the 16 DP elevation table.</p>
<p>So I'll use these values here to create my shadow styles.</p>
<p>So I'll create a key shadow and an ambient shadow.</p>
<p>Now on that key shadow, you can see that we have two types of key shadow styles.</p>
<p>We have the Umbra key shadow style and the penumbra key shadow style.</p>
<p>So I'll create an ombre key shadow style first, and for that the Opacity value is set to 14.</p>
<p>So I would come out keep this selected, I would add an effect property, and I would set the Opacity value here to 14, and the X property is set to zero with the Y property set to 16.</p>
<p>So outcome here for the Y property out set this to 16, the X property has already set to zero.</p>
<p>Now the block properties 24, and the spread properties too.</p>
<p>So for the block property out, set it to 24.</p>
<p>And for the spread property out set it to.</p>
<p>And here we have our umbrella key shadow effect.</p>
<p>So I would go ahead and create for the panel, Brad key shadow effect and the MPs shadow effects.</p>
<p>So I would speed up this process also, and I'll come back when I'm done.</p>
<p>So these are the shadow styles that I have created.</p>
<p>So I'll go ahead and out, save them to my style library, the way to do that is pretty easy.</p>
<p>Select this rectangle there, then come here in the Effects section, click on that style icon there.</p>
<p>And you can call this whatever you want to call it out call this light shadow out cold this other one here, mid shadow, and out cold this peak shadow and that's okay.</p>
<p>So far, I have my textiles created, I have my color styles created, I have my effects styles created and I have my grid styles created.</p>
<p>Now at this stage, we are ready to start designing the components for our app.</p>
<p>So I would like us to go ahead and start that.</p>
<p>So the method I would like to use in the designing of our components will go like this, I'd like for us to design our components based on the user task of this app.</p>
<p>Now the first task I'd like us to look at is the authentication task.</p>
<p>So for this task, I'd like us to design all of the components that will be needed to complete this task.</p>
<p>So let's come up here, let's have a text here, I would zoom in to 200.</p>
<p>And I would have a text here, this is going to be the section where I would have all of my authentication components.</p>
<p>So I would come here, I would select this textile to have that there.</p>
<p>So for the authentication task, we have the login form and the signup form.</p>
<p>So for the login form, which components do we have there, we have the input field, and we have the button.</p>
<p>So I would go ahead to design the input field.</p>
<p>So I would come here, I'll just say, inputs.</p>
<p>Now this is going to be my placeholder.</p>
<p>So I would come here and I'll use the body small text for that.</p>
<p>And I would keep it selected, then create an auto layout on it.</p>
<p>Now when I create an auto layout, and it out, add the fill color, like this, then I'll just stretch it to this point.</p>
<p>Now I'll still keep this auto layout selected, come here and make sure that the content of the auto layout is aligned to the left.</p>
<p>And that's fine.</p>
<p>Now for the corner radius property, I would give it a corner radius value of eight to have that now outcome here and I would rename this to impute field.</p>
<p>Now while this is here, I'll select the background color for the input field itself, then the text here, I'll give it this off text color here.</p>
<p>And I'd like this input field to have a stroke color, which is going to be the color of the off text also.</p>
<p>So I can have this.</p>
<p>Now this is sorted, we are done with creating a imputes field.</p>
<p>This impute field is what we are going to reuse for the collection of emails, passwords, phone numbers, so I'll go ahead keep it selected and out, come here and click on Create components.</p>
<p>Now the next thing to create will be our button components.</p>
<p>So I would come here and I would have this text here and for that text outcome here now to select the button text for that Now I'll keep the text selected and I'll create an auto layout on the text.</p>
<p>Now outcome here, for the Button Auto Layout out, make sure the padding around items value is set to 16.</p>
<p>Now, same happened for this, the padding around items value for this input field is also 16.</p>
<p>So take note of that.</p>
<p>Now for this button components outcome here now give it this color, which is the surface color.</p>
<p>Now for the text, their outcome here, and I'll give it the surface text color, which is white.</p>
<p>Now outcome here, I would select the button auto layout, come here, now align the content of that auto layout to stay at the center.</p>
<p>Still keep it selected, come here and give it a corner radius of eight.</p>
<p>And there we have our button components created.</p>
<p>So I would come here out, rename this to button, then come here and click on Create components.</p>
<p>And there we have created our button components.</p>
<p>Now the next component I'd like for us to create here under the authentication task will be the input field, but the users will have to impute their verification code in now that input field will not look like this, it's going to look different.</p>
<p>So I'd like for us to go ahead and do that.</p>
<p>So I would come here, out of habit text here, let's just say zero.</p>
<p>And I'll keep the number selected, then go ahead and create an auto layout on that number.</p>
<p>Now I'll keep the auto layout I just created selected, come here and align the content of the auto layout to stay at the center of the auto layout, then I'd come here and add the fill color to that auto layout.</p>
<p>Now I'd come here, I would select the pencil.</p>
<p>And I'll just draw a line horizontally, then I'd click on Done.</p>
<p>And this line I just created here will be grabbed and taken into that auto layout that has that number zero.</p>
<p>And you can see that the line is placed here.</p>
<p>Now what I'll do is this outcome here, inside this auto layout, now I would select this straight line that I created, which is called vector one here, when I select it, I would come here and now change its horizontal resizing value from fixed width to fill container.</p>
<p>So that I can have that now I have a problem here, the padding around value for this auto layout is really big.</p>
<p>So I would select the auto layout outcome here and I would set it eight.</p>
<p>When I set it to eight, it's going to look like this.</p>
<p>Now I'd like it to be like this, because if I am placing these components on my screen, I would most likely increase the width.</p>
<p>And as you can see, when I increase the width, the number zero just stays the way it is.</p>
<p>But the line itself stretches across the container, which is actually what I want.</p>
<p>So this is okay, now, now seems the verification code will be a four digit verification code, I like to have this component go into four places.</p>
<p>I'll go ahead and do that.</p>
<p>So I'll keep this component selected.</p>
<p>And I'll create another auto layout on top of it like this.</p>
<p>Now this auto layout that I just created is called prim to out, keep it selected, come here and now it sets its direction property to horizontal direction.</p>
<p>When I set that to horizontal direction, I would come here and I would set the padding around items value to zero, just like that.</p>
<p>Now outcome here now expand the frame to auto layout.</p>
<p>Now just so that I can access the frame one Auto Layout inside of it.</p>
<p>Now when I select that frame one Auto Layout inside of it, I'll duplicate it.</p>
<p>And you can see that I have duplicated this into four places.</p>
<p>Now I'll come back here how to select the frame to auto layout, and how to set the spacing between items value to zero, just to have this now let's check to see if this auto layout itself is a responsive auto layout.</p>
<p>So I'll keep it selected still an outcome here and I'll try to expand it.</p>
<p>And as you can see if I expanded horizontally, the layout itself is not responding to that expansion.</p>
<p>So I would Ctrl Z to go back to how we were before.</p>
<p>And at this stage, what I'm going to do is this out, select the individual sub Auto Layout inside this main Auto Layout out select this one, which is frame one outcome here now to set its horizontal resizing value to pill container.</p>
<p>And I'll do that for all of them just like that.</p>
<p>Now when I select the frame to auto layout now and I increase the size horizontally, you will see that it's all responsive.</p>
<p>And that's what I want.</p>
<p>So I would keep this here, I would rename these two, verification imputes keep it selected, come here and click on Create component and that's sorted.</p>
<p>So at this stage, I'd like for us to go ahead and create our authentication screams.</p>
<p>So let's create a section for that.</p>
<p>Not a page actually.</p>
<p>I'd say authentication screams authentication Hi Fi screens just like this.</p>
<p>So I would come here, I'd have an iPhone that in Promax screen here, and I would rename this, make sure you rename your layout at this stage.</p>
<p>So I would rename this to splash.</p>
<p>And we all know what the splash screen is.</p>
<p>Yeah, that's the screen you see, when you launch an app for outcome here, I'll change the color of the splash screen to this.</p>
<p>And on the splash screen, I'd like for us to have the logo of the brand.</p>
<p>And the logo of this brand is really easy.</p>
<p>It's just VXS t, just like that.</p>
<p>So I would keep the text selected outcome here, now go with the headline to bold, and I'd work with this.</p>
<p>So I'll keep that text selected, come here and align it horizontally and align it vertically.</p>
<p>And that's okay.</p>
<p>So this is our splash screen.</p>
<p>So after the splash screen, the next screen to create will be the screen where the user will have to select the authentication action.</p>
<p>So I will duplicate the splash screen, I'll take this out.</p>
<p>And I'll change the color of this screen now to this, then come here and rename it of selection.</p>
<p>You can call it whatever you want to call it.</p>
<p>Now over here, out, bring in the button components out, go to my Assets panel out, bring this in and out, align it to the center horizontally, now expand it to this point.</p>
<p>Now for me to expand it properly, I would need to apply my grid style on this layout.</p>
<p>So I would come here and now apply my mobile grid style here.</p>
<p>So that I can use this as my guide to properly expand these buttons.</p>
<p>So I'd like the button to take up two column grids.</p>
<p>And that's what I have here.</p>
<p>So I would come here, I'll change the text to login.</p>
<p>And I would bring in another button components here.</p>
<p>And I'll change these to get started.</p>
<p>Now outcome here, select this button components and change its color to this just to make a difference.</p>
<p>So I would keep this here.</p>
<p>And I'll keep this here.</p>
<p>And that's fine.</p>
<p>So I would select this, and now align it to the center vertically.</p>
<p>And I'd bring this in place this Get Started button right under this login button.</p>
<p>But I'll use the row grid to ascertain the space value out give to that.</p>
<p>So I have 1234 rows here, and it's into four places is 32.</p>
<p>So I have a 32 px bottom margin space between this login button and the get started button.</p>
<p>Now I think the row grid is not really visible.</p>
<p>So I would come here, I'd go to my row grid saved style, I'd click on Edit style out, select rows and out, increase the opacity of that color to 20.</p>
<p>So this is sorted, this cream is sorted.</p>
<p>Now if the user goes ahead to click on the login button here, it means the user will go to the login page, right.</p>
<p>So I'll create that now.</p>
<p>So let's zoom in.</p>
<p>Let's take this out.</p>
<p>And let's click on layers and change the name of this frame to log in page.</p>
<p>And what I'll do is this when I zoom in, I'll bring this here.</p>
<p>So what I'll do is I'll just have logo stay here, out, come here now to select headline to bold, that's too big out GUI headline three board, that's okay.</p>
<p>So out align it to stay at the center horizontally, and I'll bring it down to this point, then I'll change the color to this.</p>
<p>Now what I'll do next is to have my login form created.</p>
<p>And I'll do that with my input field here, which is this.</p>
<p>Now I'd like this input field to stretch from here to here, just like that.</p>
<p>Now, this input field would have a label here.</p>
<p>So I'll just give it a label here that says enter email address.</p>
<p>I'll keep label here.</p>
<p>Now the space between this liberal and this input field is 16 px have two row spaces between this label text and this input field.</p>
<p>Now for the input field, I'll change the placeholder text from inputs to enter email address.</p>
<p>That's okay.</p>
<p>So I would come here, I'd have another input field here, which is going to be used for the password.</p>
<p>So I'll change the placeholder here to enter password.</p>
<p>And I'll give this input field its own label or duplicate this.</p>
<p>And first of all, I would say okay, the space between this input field and this liberal text should be 1234568 times six is 48.</p>
<p>So I'd like a 48 px margin space between this input field and this liberal text.</p>
<p>So that's sorted.</p>
<p>Now I'd like a 16 px space between this liberal text and this impeach field.</p>
<p>So I would come here and I'll edit this from enter email address and password.</p>
<p>That's okay.</p>
<p>let's align this properly.</p>
<p>So the next thing I'd have here is the login button.</p>
<p>So I'll bring a button component here.</p>
<p>And for this button components, I'd like to have your margin space here of that two px.</p>
<p>So it's going to be 1234.</p>
<p>So I'll bring this here, place this there.</p>
<p>And let's zoom out, let's stretch this to this point and stretch this to this point, then I'll change the text of the button to login.</p>
<p>Let's see how it looks.</p>
<p>Okay, this doesn't look really good, the spacing is not really consistent.</p>
<p>So I'll zoom out.</p>
<p>And I'd have the space between this label text and this input field to be 32 px, actually, so it's going to be 1234.</p>
<p>So I'd have that stay there.</p>
<p>And I'd have this stay here.</p>
<p>Then I'd have 123456, which is 48 px.</p>
<p>So let's see.</p>
<p>Hi, looks.</p>
<p>So this looks okay.</p>
<p>Now, I like us to have a text here, which is going to be the forgot password.</p>
<p>txt, forgot password.</p>
<p>So let's keep this here.</p>
<p>And let's have that stay 16 px away from this input field and 16 px away from this button component.</p>
<p>So I would select the text, and I would make sure it is a body small text.</p>
<p>And that's okay.</p>
<p>So I'll just zoom out, you can see that we have that.</p>
<p>So I would go ahead and create the signup page for our authentication task.</p>
<p>So I would come here, I'll click on layers, and I would rename this to sign up page.</p>
<p>And if you come here, the only difference we are going to have here is the fact that we are going to have an additional input field to collect the user's phone number.</p>
<p>So this means that I'll take this out for now, take this out for now.</p>
<p>And I'd have another placeholder here, which is going to have a margin top space of 32 px, which is 1234.</p>
<p>I'll bring this here and out, bring in an input field, which is going to stay here, then out, stretch the input field to this point.</p>
<p>Now I'll use this second input field to collect the user's phone number.</p>
<p>And I'll change the placeholder here to phone number, then I'll use this thought imputes field to collect the user's password, just like that.</p>
<p>Now I'll go ahead and I'll bring in a button here.</p>
<p>And this button is going to have a 48 px margin top space, it's going to be 123456.</p>
<p>I'll bring this here.</p>
<p>And I'll change the text here to sign up.</p>
<p>So I'll zoom out, I'll keep this selected out, stretch this to this point and out, stretch these to this point.</p>
<p>And that sorted, so we have created a login screen and our signup screen.</p>
<p>Now when the users click on the Sign Up button here, the users will be taken to that page where they would have to enter the verification code that was sent to their phone number.</p>
<p>So we are going to go ahead to create that page.</p>
<p>So I would come here and out rename this verification page.</p>
<p>And I'll take all of this out over here.</p>
<p>After the logo, I would have a rectangle that's going to be that's going to be this big.</p>
<p>I like the rectangle to be 48 px tall rectangle, just like this out, zoom out, or have this here and out, stretch the rectangle to this point.</p>
<p>And I'd have the rectangle have this background color.</p>
<p>Now on this rectangle, I would have a text that says a verification code has been sent to just like that.</p>
<p>So I'll keep this text here.</p>
<p>And I'll use a body small text for that, then out align the text to the center horizontally, then I'll keep this text aligned to the horizontal center of the page, just as the like this.</p>
<p>And that's okay.</p>
<p>And that's okay.</p>
<p>So I'll go ahead and bring in that input components for the verification code.</p>
<p>But before I do that, let's change the color of this text.</p>
<p>So I would come here, and I'll give you this color.</p>
<p>Then I'll click on the Assets panel now and I'll bring in this component.</p>
<p>Now for this component, I'll keep it selected First things first, I'll change the color of that components out, select the individual items inside the components.</p>
<p>And now change these to the background color that we have.</p>
<p>Just like this.</p>
<p>And that's okay.</p>
<p>Now for the lines that we have, I'll change the color of all those lines to this.</p>
<p>And for the numbers.</p>
<p>I'll change the color of the numbers to this.</p>
<p>And that's okay.</p>
<p>So I would keep this selected.</p>
<p>Now increase the width to this point.</p>
<p>So let's zoom in.</p>
<p>So now we can organize this properly.</p>
<p>So I will keep this here and how to snap the heights.</p>
<p>This points just like this.</p>
<p>So I'd have a placeholder text there.</p>
<p>That's going to say enter very occasion code, just like this.</p>
<p>And now change the color of that text to this.</p>
<p>So let's go ahead, and let's change the color of this label text that we have here to this, change this to this, come here, change this to this and change this to this.</p>
<p>Now for the Enter password text here, I'll change this also.</p>
<p>And for the Forgot Password text, I'll change this.</p>
<p>And that's okay.</p>
<p>Now, let's go back to our verification code page.</p>
<p>And let's have this button come up to this point.</p>
<p>So it's going to be 123456.</p>
<p>Out keep this here, and I just have a verified text, just like that.</p>
<p>So at this stage, we have created a verification page for our authentication task.</p>
<p>Now when the users click on the Verify button, we are going to need a pop up that would show up on the screen to let the users know that their verification has been successful.</p>
<p>Now, how do we create that pop it simple outcome here, I would select the frame to now creates a pop up just like this.</p>
<p>Now the reason I'm creating this here is so that I can use the width of this layout to set the width of this pop up.</p>
<p>Now the definite way to do this is this, if you come here, and you select this page, you will see that the width is 428.</p>
<p>Now the margin space on this layout is 16.</p>
<p>Here, and 16 here, which is 32, right, so to get the container space here, and use the width of the container space for this, my pop would be me subtracting 32 from 428.</p>
<p>So I would just select this outcome here, I would say four to eight minus 32.</p>
<p>And that's going to be the width for my pop.</p>
<p>And this is it as easy as that.</p>
<p>So I would come here and I'll give it a corner radius of eight, then I would go ahead and I'll give it this background color, when I give it this background color, then I'll have a text right inside that layout that's going to say, pull number verified, or whatever you want to say.</p>
<p>So I would come here and I would select a better textile.</p>
<p>For that, I would go with the body large textile just like this out, align it to the center horizontally, now out bring in the button components here and out have a Proceed button here that the user will click on to go to the homepage.</p>
<p>And we are done creating this.</p>
<p>So I would select this, go to the Layers tab and out, call this verify popup just like that.</p>
<p>So that pop up is going to show up when the user enters their verification code here and click on the Verify button.</p>
<p>So I'll grab this now.</p>
<p>And I'll place it here.</p>
<p>And that's fine.</p>
<p>So at this stage, I'd like to say that we are done with creating all of the screens that we need for our authentication task.</p>
<p>So this is going to take us to the next task of our app.</p>
<p>And that task is actually the fund task where users will have to fund their wallets or their accounts so that they can invest.</p>
<p>So I would come here, and I'd have this here.</p>
<p>I'll change this to fund accounts.</p>
<p>So all of the components that are heavier will be the components that will aid the user to fund their accounts on this app.</p>
<p>So let's go ahead and let's do that.</p>
<p>Now what you need to take note of is this, for a user to fund the account, the user will have to go to the homepage of the app first, right? Because it is from the homepage, that dude see the fund account button.</p>
<p>So what does this mean? This means that we need to create components for the homepage and have our homepage sorted first, before we handle different account routes.</p>
<p>So let's go ahead and let's do that.</p>
<p>On the homepage, the first component that we are going to have will be a card components that will display the balance that we have in our account.</p>
<p>And it is still on that card components that we are going to have the one account button.</p>
<p>So let's go ahead and let's create that.</p>
<p>So I would have a text here is going to say primary accounts, I would keep that text selected.</p>
<p>And I would set the typography style to body small boat.</p>
<p>Now let's zoom in to 200.</p>
<p>So this is it.</p>
<p>Now outcome here and I'll create another text, which is going to be like the account number or the account ID I would say this and I'll keep that selected also.</p>
<p>Now I would set this to body small.</p>
<p>So now I would select both of these, and I'll create an auto layout on the both of them.</p>
<p>Now when that auto layout is created out make sure that the padding around items value is set to zero for now.</p>
<p>Now outcome here How to select this text and how to set its horizontal resizing value to fill container out, select this here, and how to set its horizontal resizing value to fill container.</p>
<p>And for the height outcome here and out sets the height property here to auto height to make it balanced.</p>
<p>Now we have this created to outcome here, I'll add a fill color to this.</p>
<p>Now, I'll duplicate this, I'll bring this here.</p>
<p>And I'll change this text to account balance, or let's just say available balance.</p>
<p>Actually, that's not the account balance, I would say available balance, and here I'll write down the available balance, that's fine.</p>
<p>So I'll keep this here also.</p>
<p>Now, what I'll do is I would select these two auto layouts, and now add an auto layout on the both of them for this new auto layout that I have created, I would come here and I would set the spacing between items value to 24.</p>
<p>And out select this auto layout that inside this new auto layout, and how to set its horizontal resizing value to fill container.</p>
<p>And I'll do that for this also.</p>
<p>Now I would select this new auto layout and add a fill color of white to it to have this now you can see that this is actually responsive.</p>
<p>And that's okay.</p>
<p>Now, I'd like to bring in a button component and place it inside this auto layout so that that button will be used for the font accounts action.</p>
<p>So I would come here and bring in a button component here, then how to select that button component in the in the design tree here, hold it and grab it into this frame seven auto layout, which is our auto layout.</p>
<p>And you can see that the button component is placed inside this auto layout.</p>
<p>Now I'd like this button component to look different.</p>
<p>So I would keep it selected.</p>
<p>Come here and I would set its top padding value to eight and its bottom padding value to eight.</p>
<p>So I can have this now change this text to font accounts, just like this.</p>
<p>And that's okay.</p>
<p>Now I'll go to the feather icons plugin.</p>
<p>And I look for an icon that out place on the right side to make the components just look better.</p>
<p>Let's come in here, let's just type in home.</p>
<p>I'll bring this in actually bring this here and replace it here.</p>
<p>Now I would select all of these and I'll create an auto layout on all of them.</p>
<p>Now a new auto layout called frame eight has been created.</p>
<p>Now inside this frame eight auto layout, we have this auto layout here and this icon.</p>
<p>So I would select this auto layout now that's inside the frame.</p>
<p>It's auto layout.</p>
<p>And now to set the value for its horizontal resizing property to fill container.</p>
<p>And I'll leave this set to fixed we know how to select the frame.</p>
<p>It's Auto Layout now, which is a main Auto Layout now, and I would come here and I would set the spacing between items value to 24.</p>
<p>When I do that, I would come here and add a fill color to this.</p>
<p>Now add the fill color to the auto layout to have this.</p>
<p>And the final thing I'll do here is to come here and set the padding around items value to 16.</p>
<p>When that's done, I'll give it a corner radius of eight.</p>
<p>To have this now I can expand this to this point like this.</p>
<p>And you can see that this component is responsive.</p>
<p>And that's that.</p>
<p>So let's go ahead and let's play around with the colors of the elements on this component.</p>
<p>So I would select this text here, and I'll give it this color, I would select this now give it this color do same for this and do same for this then for this out select the icon itself, and that's fine.</p>
<p>So I would rename this to balance card, or whatever you want to call it.</p>
<p>I will keep it selected and now click on Create components.</p>
<p>And here we have our components created.</p>
<p>So on the home page Still, I'd like to display a list of recent transactions that's been carried out on the app.</p>
<p>So let's go ahead and let's create a component that's going to serve that purpose.</p>
<p>So I'd come here out create a text out call that deposit come here now to select the body large bold text then I'd come here now create another text and I'd have this which is going to be a dates that deposit happened.</p>
<p>So how to select these two text and how to create an auto layout on the both of them.</p>
<p>Now how to select this text inside the auto layout and how to set its horizontal resizing value to fuel container.</p>
<p>Now do that for this also.</p>
<p>Now out select the auto layout and how to set it spacing between items value to four.</p>
<p>And that's okay.</p>
<p>Now for this deposit text.</p>
<p>I'll change the color to this.</p>
<p>And for the date here.</p>
<p>I'll change its color To this, and that's okay.</p>
<p>So I'll keep this here.</p>
<p>And the next thing I'll do is to have a frame here, that's going to be 48 by 48.</p>
<p>I'll keep it selected and out, give it a corner radius of 100.</p>
<p>To make it round, then I'll go to the feather icons plug in and out have an icon there, that signifies incoming, which is this, I would select this icon now, and I'll place it on top of this 48 by 48 px frame that I created.</p>
<p>When I placed it there, I would come here now to set its constraints value two center for the horizontal axis and center for the vertical axis.</p>
<p>And that's okay.</p>
<p>Now select this frame, which is now a circle and out set its color, let's set it to green like this.</p>
<p>And for the icon, outset, it's colored this and that's okay.</p>
<p>Now for this frame, now that I have created, I'll bring you to our PC here, and how to select all of this and out create an auto layout on the both of them.</p>
<p>Now for this new auto layout, I would come here and I would set it spacing between items value to 16.</p>
<p>And I would come here now to set its alignments value to the center just like this.</p>
<p>Now out keep it selected to come here and add a fill color to it just like this.</p>
<p>Now I would come here now and I would create this text.</p>
<p>And this text is going to be a body large bold text, I would come here and create another text, which is going to just like display the balance out keep that selected and out make it a caption text, just like this.</p>
<p>Now to select both of them, create an auto layout on the both of them and sets the spacing between items value to for now to select the text inside the auto layout now and how to set its horizontal resizing value to feel container to have that and that's sorted.</p>
<p>So I'll select this now and I'll give it a fill color of white.</p>
<p>Now for the color of the text out set this to something lights like this.</p>
<p>And this will be something like that.</p>
<p>Now what I'll do is I'll select all of these and I'll create an auto layout on all of them.</p>
<p>First things first out align the content of the auto layout to stay at the center, then I'll add a fill color to the auto layout to have this now for the spacing between items value of this new auto layout.</p>
<p>Now, I like to set it to 76.</p>
<p>And that's okay.</p>
<p>Now for the padding around items value, I'd like to set this to eight.</p>
<p>And that's okay.</p>
<p>Now let's check to see if this auto layout is responsive.</p>
<p>As you can see, it's not.</p>
<p>So let's sort that out.</p>
<p>And to sort it out is really easy.</p>
<p>I would select this frame here, this auto layout here, I would select this auto layout here.</p>
<p>And I'll set its horizontal resizing value to fill container.</p>
<p>Now when I set this to fill container out, select the auto layout that's inside it, which is frame eight and out set its horizontal resizing value to fill container also, now I'll make sure all of these sets of field container so I'll select the items to be sure that they are also set to feel container.</p>
<p>Now when I select the frame 12 Now, which is our major frame, you would see that this is now responsive.</p>
<p>And that's okay, so I'll keep it selected, come here and now set the corner radius value to eight.</p>
<p>And I have this I'd like to duplicate this to have a withdrawal component where the circle is going to be red and the icon is going to be different.</p>
<p>So I would set the position of this icon to let's set it to 180.</p>
<p>That's the angle position.</p>
<p>That's what I'm setting here.</p>
<p>Or you can call it the rotation property of that icon.</p>
<p>So I'm setting it to 180 degrees.</p>
<p>And I'll change this with roll.</p>
<p>Then you can change all of these details.</p>
<p>If you want to change them out, select the circle itself, which is this frame, and I'll change the color to this and that's okay.</p>
<p>So outcome here out, select this out, rename this to withdraw our card, keep it selected, make it a component, okay, that's supposed to be deposit card.</p>
<p>So out select this column here and out, rename this to deposits card.</p>
<p>Keep it selected.</p>
<p>Come here and click on Create components.</p>
<p>Then select this.</p>
<p>Rename this to weave Travel Card, keep it selected and make it a component and that's sorted.</p>
<p>Still on the homepage.</p>
<p>We are going to have a banner that will be used to copy referral links.</p>
<p>So I would go ahead and out creates that.</p>
<p>So I'd have this text here.</p>
<p>that's going to see invites your friends out, keep that selected.</p>
<p>And I would go with this textile here, which is the body large bold textile.</p>
<p>And I'd have another text here, that's going to be invite your friends with this pack code.</p>
<p>And I'll go with the caption textile here.</p>
<p>And that's cool.</p>
<p>So I would select this, when I select it, I would create an auto layout, and outcome out sets the spacing between items value to eight, then out, select the text items inside this auto layout and how to set these to fill container.</p>
<p>And I'll do that for this also.</p>
<p>Now the next thing I'd like to do is to have a frame layout here, that's going to be 48 by 48.</p>
<p>And I'll keep it selected still out, give it a corner, reduce value of 100, then come here and give it that color.</p>
<p>Now I would go over to the feather icons plugin and Outlook one and I would look for an icon I can use on that.</p>
<p>So I like to use this icon here, I would select it, or bring it here and place it on this frame layout.</p>
<p>Now when I placed there, I would make sure it's at the center, then I'd come here now to set its horizontal constraints value to center and its vertical constraints value to center.</p>
<p>And that's okay, now select that icon, then I'll set its color to this.</p>
<p>And that's okay now to select all of this creates an auto layout on it.</p>
<p>So I would come here and I would align the contents of that auto layout to always stay at the center.</p>
<p>Now I'll keep this auto layout selected, and I'll give it a fill color which is going to be the background color like this.</p>
<p>Now, I would select this auto layout that is inside this main auto layout.</p>
<p>Now as you can see, it's the brim 12 auto layout that has this text, when I select it out, come here, and I'll set this to fill container.</p>
<p>And when I select the main auto layout, now you'd see that this is a responsive auto layout, which means we are good to go.</p>
<p>Now for the spacing between items value of this auto layout, I like to set it to 24.</p>
<p>And for the padding around items value, I'd like to set it to 16.</p>
<p>To have that, then come here and set the corner reduce value to eight.</p>
<p>And here we have a component.</p>
<p>So I would keep this selected.</p>
<p>Now rename this to refer our banner, then come here and click on Create component to make it a component.</p>
<p>And that's okay.</p>
<p>Now on our homepage, we have one final component, which is going to be a very interesting components to create.</p>
<p>And that's going to be the navigation components on our homepage, which is going to be at the bottom.</p>
<p>So let's see how we can create that components before we put our homepage screen together.</p>
<p>So I would come here and I would get the home icon from the feather icons plugin.</p>
<p>I'll type in home there, I'll bring this in.</p>
<p>Now I'd like to zoom in at this point so that you can see clearly, when I placed this icon here, I would come here and I would create a text.</p>
<p>And I'll call that home.</p>
<p>Now for this home text, I would create an auto layout on it.</p>
<p>And I would set the padding around items value for that auto layout zero, then set its alignment position to the center.</p>
<p>Now select the Home text that is inside this auto layout.</p>
<p>And now to set its horizontal resizing value to fill container.</p>
<p>Now out keep this text auto layout here, then I would select the Home icon and that text auto layout.</p>
<p>And I will create an auto layout on the both of them.</p>
<p>Now this auto layout is frame 15.</p>
<p>What I'll do now is I would come here and I would set the spacing between items value for this auto layout to for when I do that, I would come here now to set the alignments of the contents in that auto layout to always be at the center.</p>
<p>Now outcome here and how to select the Home auto layout and how to set its horizontally resizing value to fill container.</p>
<p>And that's okay, just stretch this and it's going to be sorted.</p>
<p>Now at this stage.</p>
<p>What I'll do is this out have a frame layout here.</p>
<p>That's going to be 48 by 48.</p>
<p>And I'll grab this pre empting Auto Layout now and I'll place it on this 48 by 48 px frame layout, make sure it's at the center.</p>
<p>When I place it at the center, I would select the frame 16 frame layouts, which is our 48 by 40.</p>
<p>It's layouts now and I would make it an auto layout.</p>
<p>Now when I make it an auto layout, I'll bring it here and I'll rename this to Home link.</p>
<p>Now after I rename it to HomeLink outcome here and now set its alignment to the center so that the content of that auto layout will always be at the center.</p>
<p>Now the padding top value is set to three out, set it to four, just so that we are going to have even numbers all around, I would set this to four also, and this outset four, and this outsets.</p>
<p>Four, just to have this.</p>
<p>So at this stage, what I'd like to do now is to have other navigation links.</p>
<p>So I'll keep this home link Auto Layout selected, and I'll create another auto layout on top of it.</p>
<p>Now this auto layout that I just created has a padding around items value of 16.</p>
<p>Yeah, I'll leave it set to 16.</p>
<p>Because actually, that's what it's supposed to be now outcome here out, expand this new auto layout, and how to select the Home link or to layout and I'll duplicate it like this into three places.</p>
<p>And that's because I want to have just three items there.</p>
<p>Now outcome here, I'll change this from home to invest.</p>
<p>And I'll change this from home to transact.</p>
<p>Let's select our frame 16.</p>
<p>And let's add the fill color to it to have this.</p>
<p>So if I expand the frame 16, you'd see that the icon and the text is just that it's not responsive.</p>
<p>So I'd like to change that.</p>
<p>So to change that out, select this home link sets these to fill container, select this, do that also select this and do that also.</p>
<p>Now when I select frame 16, and I increase the width horizontally, you would see that this text wrap into the next line is actually fixed.</p>
<p>So for this icons, let's go ahead and let's change this icon to a better icon and these two are better icon.</p>
<p>So I would come here, I would go to the feather icons plugin.</p>
<p>And I would like to have this icon.</p>
<p>So I'll bring this here.</p>
<p>And I would come in here and I will trace the auto layout that has that you can see it's still called Home link, I'll change that to invest link, when I change it to invest link, you'd see that to have the home icon inside here.</p>
<p>So I would come here now, I would select this bar chart icon now.</p>
<p>And I'll take it inside the InVEST link auto layout.</p>
<p>Now place it right inside here.</p>
<p>And you can see that it is here at the bottom.</p>
<p>So I would select the Home icon and out, delete it with the delete key on my keyboard, then come here, grab this invest icon, hold it and take it upwards like this.</p>
<p>So I'll go ahead and I'll do same for the transact link here.</p>
<p>So I'll keep this selected.</p>
<p>Come here out, rename this to bottom navigation, keep it selected and click on Create components and that components has been created.</p>
<p>So at this stage, we can go ahead to make use of all of these components in designing our homepage.</p>
<p>So to design our homepage, out, come here out, select the frame to and I'll bring in an iPhone fatin Promax frame here.</p>
<p>Now zooming to this point, now I would select this iPhone 13 Pro Max frame, rename this to home.</p>
<p>When I do that, I would come here and how to apply the grid style on it.</p>
<p>And when I do that, let's zoom in to 200.</p>
<p>out go ahead and I would bring in the menu icon using the feather icons plugin.</p>
<p>So I'll use that one there.</p>
<p>Now whenever you bring in an icon and you want to place it into a layout, make sure the icon is inside that layout here in the design tree.</p>
<p>As you can see, currently, this icon which is aligned justified is not placed inside this layout, which is our homepage.</p>
<p>So what I'll do is I would come here in the design tree, click on it to select it, hold it and drag it into the home layout.</p>
<p>And as you can see it is now inside the home layout.</p>
<p>So I would come here, and I'll place this here.</p>
<p>So I would count it row spaces from the top 1234567 and eight.</p>
<p>And that's okay.</p>
<p>So I'll have a text here.</p>
<p>So I can come here and I can say hi and for laka.</p>
<p>Now I'd like to call your attention to something important.</p>
<p>And that is the fact that as you can see here, I have the name of the user written here, which is N for lucky.</p>
<p>Now the question you should ask is this, how did I arrive at displaying the name of the user here when in the signup form, I did not collect the name of the user.</p>
<p>If you remember, in my signup form, I only collected the email address the phone number and the password of the user, which means that the app itself does not have a record of the name of the user.</p>
<p>So the question you'd ask, which is no malice.</p>
<p>How did I arrive at displaying the name of the user here? Now this is going to be your first assignment in this course, because I'd like you to come here in the authentication section here and refactor the authentication flow here.</p>
<p>To collect the name of any user that's signing up to this app.</p>
<p>Now I'll leave this open without giving you a guide on how to do that.</p>
<p>I'd like to see your thoughts process on how to refactor this authentication process with the best experience.</p>
<p>And also with the fact that you would collect the name of any user signing up to this application.</p>
<p>If you think coming here and adding another field for the name collection is fine, go ahead and do that.</p>
<p>If you have another idea that can make the experience better, go ahead and implement that.</p>
<p>Now when you implement the name collection in the authentication task here, go ahead tagged me on social media for my comments.</p>
<p>That's your first assignment in this course, then I can have another text here.</p>
<p>I'll bring this here.</p>
<p>Now the next thing I'd like to have here is the balance card.</p>
<p>So I would come here in the Assets panel, and I'll bring this component in like this.</p>
<p>Now, I'd like to have four row spaces between this text and the balance card.</p>
<p>But before I do that, I like to keep this balance card selected, then come here and apply my shadow style that I saved.</p>
<p>So it so I would go with image shadow like this.</p>
<p>Now let's zoom into this point.</p>
<p>And let's make sure we have four row spaces.</p>
<p>And that's okay, let's zoom out.</p>
<p>Now what we are going to do is to stretch this to this point.</p>
<p>And that's going to be successful because our components is a responsive component.</p>
<p>So nothing is going to break.</p>
<p>And this is okay.</p>
<p>So I would come here at the bottom here, out, snap this to this roll line.</p>
<p>And that's sorted.</p>
<p>So the next thing I'm going to have here is a text that's going to say recent transactions out, keep that selected and out go with a body large bold text.</p>
<p>So I'll make sure I have 1234 Group spaces there.</p>
<p>And that's sorted.</p>
<p>So I'd have that there.</p>
<p>And I would select a different color for that.</p>
<p>I'll go with this.</p>
<p>Now for this also out have this color set this now just in case I forget to set the color of the text as I proceed, you go ahead and do that.</p>
<p>So I would select this icon also now change the color to this, that's okay.</p>
<p>Now right on that this will be sent transactions text out have those transaction cards there.</p>
<p>So I'll bring this in, which is the opposite cut out, give me the shadow style outcome here.</p>
<p>I'll give it a meet shadow style there.</p>
<p>Let's zoom out to this point.</p>
<p>And I'll just stretch this to this end here.</p>
<p>And I'll make sure this snaps properly too.</p>
<p>And that's not going to be a problem because a component is responsive.</p>
<p>So let's look at the space in between this card and this text out zooming, you can see we have 123 I'll make this four.</p>
<p>Let's zoom out.</p>
<p>Okay, that's actually too far away.</p>
<p>So I'll bring this here, I'll have two row spaces.</p>
<p>Okay.</p>
<p>So I would have this one here.</p>
<p>So I'd have two spaces from this text to this card.</p>
<p>And if I select the text, you'd see that I have one row space and two space before this card.</p>
<p>And that's okay.</p>
<p>So what I'll do now is I would go ahead, I'll duplicate this.</p>
<p>And when I duplicated, I'd make sure I have just one row space, which is SPX, I'll bring in this other one, which is four, which is for a withdrawal event.</p>
<p>Outcome.</p>
<p>Yeah, I'll give it a meet shadow out, zoom out and out, snap this to this points.</p>
<p>And I'll make sure it's just eight px space.</p>
<p>So I'll bring this here and that's okay.</p>
<p>Now I'll have just three recent transactions here.</p>
<p>So I'll go ahead and bring in this referral banner and upload it here.</p>
<p>So I'll make this snap to the end also, just the other point, now zooming, and I'll make sure I have a consistent space in here.</p>
<p>So I'll have a 48 px margin space over here, which is going to be six row spaces, right.</p>
<p>So I'd have 123456.</p>
<p>So I'll bring this in place here.</p>
<p>So I'll zoom out, and at this point, what I'll bring in will be a bottom navigation components.</p>
<p>I bring it up let's see here.</p>
<p>Let's zoom in and let's make sure this is properly placed.</p>
<p>As you can see I have properly placed this so I would keep it selected.</p>
<p>Come here and I'll change the fill color to this out select this, change the fill color to do this, select this select this I'll change the fill color to this now select the icon itself now change the fill color to this or do that for this also.</p>
<p>And I'll do that for this also.</p>
<p>Now for the text out select the text and I'll change the fill color to this and that's okay.</p>
<p>Now for the text color of this navigation link.</p>
<p>I like the text color actually to be pure white so that it can be really present there.</p>
<p>And I think this is better.</p>
<p>And that's it.</p>
<p>So we have just designed our homepage now using the components that we created.</p>
<p>So I would also advise that while designing, it's also good most times to test what you're designing, so I would select this column here, and I would click on present to see how this is going to look like actually.</p>
<p>So this doesn't look good like this, I like to present this inside an iPhone device.</p>
<p>So outcome here, click on prototype, click on prototype Settings and select a device here, which is iPhone 13 products.</p>
<p>When I do that outcome, help select this layout once more, and I'll click on present again, that's going to sort it.</p>
<p>And this is what we have, this looks good, you can come here and present this in full screen just like this, to see it better.</p>
<p>So let's go ahead and let's keep designing our application.</p>
<p>So I'll press the Escape key on my keyboard to go out of that full screen display and not come back here.</p>
<p>So the next action I'd like to design for will be the action of the user clicking on different accounts button.</p>
<p>So when the user clicks on the fund accounts button, I'd like to display a pop up that will allow the user choose the method in which they would like to fund the account with and that's easy, because we have actually created a pop up before.</p>
<p>So I would come here, I'll duplicate this pop pop, and I'd have the Pop Pop stay here.</p>
<p>And right inside this pop up here, I would have one button here, which is going to say bank transfer.</p>
<p>And I'd have another button here that's going to present the option to fund the account with a debit card.</p>
<p>So I'd have this the here and now expand this to this point.</p>
<p>Now expand this to this point.</p>
<p>I'd also keep this here and expand this to this point.</p>
<p>Now to expand this to this point, I'll keep it selected and how to center it horizontally.</p>
<p>So outcome here, I'll bring this downwards.</p>
<p>And I'd have it textured that's going to say select method.</p>
<p>So I'll change the color of that text to this.</p>
<p>And that's going to be cool.</p>
<p>So I would select this pop now, and I would rename it from verify pop to bond method pop up, keep it selected, and I would make it a component.</p>
<p>And that's going to be it.</p>
<p>So when the users click on bond account here, they would have this pop pop show up asking them to choose the method in which they would like to fund their account with now let's say the select the bank transfer method, they will be taken to the page where they would have that happen.</p>
<p>So for that out creates that page now.</p>
<p>So I would come here, I'll duplicate this, and I would rename it bank transfer, when I rename it to bank transfer, I would come here and I would take all of these outs.</p>
<p>And I would also take the bottom navigation out also.</p>
<p>So what I'd have here is an icon that will direct the users back to the previous page.</p>
<p>So I would go to further icons.</p>
<p>When I come here, I would scroll down, and I would select this icon for that.</p>
<p>So I'll take this out.</p>
<p>And I'll bring this here.</p>
<p>And as you can see, this icon is not inside this layout.</p>
<p>That's why this smart guy is not active.</p>
<p>So I would come here, I would select this icon and I'll take it into these layouts, just like this.</p>
<p>Now when I select it, and I move it around, you'd see that the smart guide is active.</p>
<p>So I'll make sure that I have it spaces from the top 12345678.</p>
<p>And that's correct.</p>
<p>So I will keep that icon select and I'll change the color of the icon vector to this.</p>
<p>And that's okay.</p>
<p>The next thing I'd have here is a title for this page.</p>
<p>That's going to say bank transfer, you can call it whatever you want to call it.</p>
<p>So I'll use the headline three bold text for that.</p>
<p>I'll keep that there how to center this horizontally actually, to be sure it's at the center horizontally.</p>
<p>And that's fine.</p>
<p>Now I'd come here, and I'd have bits here.</p>
<p>So I would have these details here.</p>
<p>So what I'll do is I'd make sure I have 1234.</p>
<p>Okay, I'd have it's row spaces there, I'd have 12345678.</p>
<p>So what we are going to have here is the destination account details where the user should make the bank transfer to so here's the account number.</p>
<p>Here's the account name and here is the bank name.</p>
<p>And that's it.</p>
<p>So I would come here and I'd have a button component here, out align it to the center and I would stretch it to this point and stretch it to this point also, I would have 123 456.</p>
<p>So I have seven, and eight.</p>
<p>So I'd have a two row spaces there.</p>
<p>Now what I'd have on this button will be copy account number.</p>
<p>So the user can just click on this button to copy the account number here.</p>
<p>So I have sorted the routes for funding the account on this app with bank transfer.</p>
<p>So let's go ahead and let's create the page where the user will use to fund the account with their debit card.</p>
<p>So outcome here, so I will change this debit debit card, or align this to the center, that's okay, I'll take this out, then I'd come here, I'll take this out also, then I'd have all of this here.</p>
<p>So I would have it row spaces from this icon also.</p>
<p>So let's zoom in so that we can count better.</p>
<p>So I would have 12345678.</p>
<p>I'll keep this here.</p>
<p>And I'd have one two, I'll have that there.</p>
<p>out, zoom out.</p>
<p>So this is going to be the page that will enable the user fund their accounts on this app with a debit card.</p>
<p>So what we have here is, the user will enter the amount and have the option to select that they want to use the existing card that they have on this app, or they would like to add another card.</p>
<p>So let's fix some alignment issues here.</p>
<p>Let's keep this there, come here and keep this here also, then come here, balance that's there.</p>
<p>And keep that there.</p>
<p>Also, I would also come here and make sure that this is sorted also here.</p>
<p>So for the action of adding another card, we are going to see how to do that as we proceed for now let's go ahead and let's have a button component here, align that to the center horizontally, keep that there, keep that there, then for the text out, say font accounts.</p>
<p>And that's that.</p>
<p>So if the users click on the font accounts button, they would have this pop up show up for them to choose the method they want to use, when they select the bank transfer method, they would have this page show up, if they select the debit card method, they would have this page show up also, they would have this page show up.</p>
<p>Now, if the user clicks on this fund accounts button, when they want to fund the account with a debit card, the user will be taken to another page, which is going to indicate that the account has been successfully funded.</p>
<p>So I'll duplicate this to have that there.</p>
<p>Now, before we work on that page, I'd like to change the name of this page from bank transfer to debit card transfer.</p>
<p>Now for this page here, out, rename it to transfer successful.</p>
<p>Come here, I'll take all of these outs.</p>
<p>I'll take this out also.</p>
<p>And I'd have a frame here, which is going to be 100 by 100 frame, that's how it's going to look like that's quite small.</p>
<p>So I'll make this 240 by 240.</p>
<p>And I'll just work with this.</p>
<p>So I'll give it this color.</p>
<p>And I'll give it a corner radius of 200 to make it a circle.</p>
<p>And I'll go over to the feather icons plugin.</p>
<p>And over here in the feather icons plug in out bring in this icon, and that icon will be placed on top of this frame.</p>
<p>Now go ahead and use the Scale tool to scale that icon to this point, just like this.</p>
<p>Now, when you scale the icon, make sure that the constraints of that icon is set to the center horizontally and the center vertically.</p>
<p>So I would come here now I would select this icon and I'll change the color of that icon to this when our habit text here that would say count funded successfully, or you can have whichever text you want to have they that's fine.</p>
<p>So I would come here and I'll change the color of this to that.</p>
<p>So after that, I would have a button component here, that will redirect the user to the InVEST page.</p>
<p>So I would say invest.</p>
<p>Now when they get this page, they would have the option to click on the InVEST button here to go straight to the InVEST page where they can invest.</p>
<p>So that's the next page we are going to look at we are going to look at creating the InVEST page where users can invest in stocks.</p>
<p>So to create that page, it means that we need to create the components that the page will need.</p>
<p>So let's go ahead and let's see how to create the components for that page.</p>
<p>So for the InVEST page, the first component I would have there will be a little card component that will be used to display the cash amount that the user has.</p>
<p>So I would come here and I would create that.</p>
<p>This is the fund accounts component section here.</p>
<p>So I would have the invest component section here.</p>
<p>And to create that card, I would have this here, I would say cash.</p>
<p>And I'll use the body small textile for that.</p>
<p>And I'd have an amount here, just any amounts.</p>
<p>Okay, so I would use body large bold here, then I'll just select the both of them, I would create an auto layout on the both of them, make sure the padding around items value is set to zero, then I'll come here and I'll add the fill color to it.</p>
<p>To have that now select the cache text and set the horizontal resizing value to fill container and do that for this or that text on the here, which is the amount of cash that the user has.</p>
<p>Now when that's sorted, select the auto layout, and then come here and set the space in between items value to for now, I'll go over to the feather icons plug in, and I'd look for an icon that I can use to represent cash there.</p>
<p>So I would scroll down and I'll look for one of the icons here.</p>
<p>So I am going to make use of this icon here, I would select it, I'll bring it here, then I would select both of these and out create an auto layout on the both of them the outcome here.</p>
<p>And I would make sure that the alignment value for this auto layout is set to be top left corner of the auto layout.</p>
<p>So I would keep this auto layout selected, I would add a fill color to it.</p>
<p>And I would set the spacing between items value to eight, then set the padding around items value to eight, then come here and I'd have the corner radius value set it also.</p>
<p>So over here, I would select this auto layout inside the main Auto Layout now.</p>
<p>And I would set its horizontal resizing value to feel container.</p>
<p>And when I do that, you will see that this component will be irresponsive components just the way I want it to be.</p>
<p>Now let's go ahead and let's set the colors for this.</p>
<p>So I will set the color of this to that now set this to this now for this icon out set the color of this icon to this.</p>
<p>So I'll keep this here, I'll duplicate it, when I duplicate it out, go ahead, change these two assets, then I'll leave the value here just like this, or you can change it if you want to change it.</p>
<p>Now the next thing I'd like to do is to take out that icon and have another icon there.</p>
<p>So I would go to further icons.</p>
<p>And I would have this selected for that.</p>
<p>So I'll bring this here, let's go to the Layers tab here.</p>
<p>And I would select the briefcase icon here, which is this, I would select it here.</p>
<p>And I'll take it into the frame 19 Auto Layout, just like this.</p>
<p>And you can see that it is staying here on the right side of the auto layout, I would grab it and I'll take it to the left side.</p>
<p>Now I'll select this one, and I'll delete it.</p>
<p>And I have that.</p>
<p>So I would select this icon now and I'll change the color of this icon.</p>
<p>And this is sorted.</p>
<p>So I would rename this to cash card, whatever you want to call it is okay.</p>
<p>And I would rename this to assets card.</p>
<p>And that's okay.</p>
<p>So I would select this, make it a component, select this, make it a component.</p>
<p>So let's go ahead and let's create the other components that we are going to need on the InVEST page.</p>
<p>So the next component, our need on the InVEST page will be an input field component that the user can use to search for top stocks that they would like to invest in.</p>
<p>So we have an input field here already created, it's already a component.</p>
<p>So what I'm going to do is out duplicate it, I'll bring it down here.</p>
<p>And I'll keep this here.</p>
<p>Now when you duplicate the components like this, the duplicates will be a child components.</p>
<p>Now, I wouldn't love to work with this as a child components.</p>
<p>So what I'm going to do is out out keep the components selected, right click on it and out select detach instance.</p>
<p>Now when I select detach instance, you would see that this is back to a regular auto layout.</p>
<p>So I would come here, and I would change the name to such impute field, then what I'm going to do is I would go to further icons now bring in a search icon, which is this out, grab it and drop it inside this auto layout, which is the search input field auto layout.</p>
<p>Now the issue is this.</p>
<p>I want this search icon to be smaller than this, because it's quite too big.</p>
<p>And as you can see it has increased the height of the impute field.</p>
<p>So I'll keep the icon selected.</p>
<p>Come here, and I'll set this to 12.</p>
<p>And I'll set this to 12.</p>
<p>And that I have that now I think 12 is too small outside this to 16.</p>
<p>And out set this to 16.</p>
<p>And that's sorted.</p>
<p>So the next thing is this, I'd like this icon to stay on the right side of this impute field.</p>
<p>So how do we do that? Just select the search input field auto layout.</p>
<p>Come here.</p>
<p>Click on the alignment and padding property.</p>
<p>then change this property from packed to space between, and that's going to be sorted.</p>
<p>Now let's change the color of that icon.</p>
<p>I'll change it from black to this.</p>
<p>Now I can select it now and make it a component.</p>
<p>And as you can see, it can be used just the way you'd like it to be used.</p>
<p>So let's go ahead and let's create the next component that we are going to have on our invest page.</p>
<p>So the next components will be the components that will display the list of stocks that are available to invest in, in this app.</p>
<p>So let's come here, let's have some space here, I'll use the brand fetch plugin.</p>
<p>To pull up the logo of a brand, I'd have this Come here, I'll type in dangoty, or press the Enter key on my keyboard.</p>
<p>And I'd have this here.</p>
<p>So I would select this out, click on it to select it, and I'd have it there in my canvas.</p>
<p>So I'll bring this here, and I'll make it a 24 by 24 frame logo just like this.</p>
<p>Now when I make it 24 by 24.</p>
<p>The next thing I'd love to have is the price of this stock, I would have that out select the caption text for that, then I would have this, then I would have this, make sure I use the caption text for that also, then I'll create an auto layout on this and I'll set the padding around items value to zero.</p>
<p>Now out select the text inside this auto layout and set its horizontal resizing value to fuel container.</p>
<p>Now, I'd like to have an icon here that will indicate decline or increase.</p>
<p>So I would go to the feather icons plugin.</p>
<p>And I would bring this icon in, and I place it here.</p>
<p>Now I'll make this icon a 16 by 16 icon just like this, when I plus here, how to select both of them.</p>
<p>Now create an auto layout on the both of them.</p>
<p>Now for the spacing between the auto layout, it's going to be set to four.</p>
<p>Now to select this auto layout that's inside this framlington Auto Layout, I am talking about the auto layout that has this number here, I would select it, when I select it, outset its horizontal resizing value to fill container, then out select the frame 19 Auto Layout now, and now add a fill color to it.</p>
<p>Now let's go ahead and let's select this icon.</p>
<p>And let's make the color to be green just indicates progress.</p>
<p>Yeah, so I would come here now, I would select both of these and create an auto layout on the both of them.</p>
<p>Now for this auto layout here, I would set the spacing between items value to eight, it's already set it for me.</p>
<p>So I'll just leave it set to eight.</p>
<p>Then I'll come here and I'll add if fill color.</p>
<p>To have this outcome here.</p>
<p>Out select this text now, which is inside this new auto layout and outset it's horizontal resizing value to fill container.</p>
<p>And for this outset, it's horizontal resizing values fill container.</p>
<p>Now when I select this frame 20 Auto Layout, as you can see here, it's a frame 20 Auto Layout, when I select it, and I resize it, you would see that it's a responsive auto layout, just like this.</p>
<p>And that's what I want, actually.</p>
<p>So I'll bring this here.</p>
<p>Now I'll go ahead to create a text that will signify the title of that stock, I'll just call it dang.</p>
<p>Now I'd come out set this to body large bold, and I'd have this day here with this text.</p>
<p>Now what I'll do is I would select this and this text, and I'll create an auto layout on both of them.</p>
<p>Now outcome here now add the fill color to this auto layout first, then come here and align the contents of that auto layout to the center.</p>
<p>After that, I would set the spacing between items value of that auto layout to eight to have this now bring this here and I'd have this here.</p>
<p>The next thing to do is to have all of these selected, then out add an auto layout on all of them.</p>
<p>Now for this new auto layout.</p>
<p>Now, I would set the spacing between items value to eight, then come here, select this auto layout and set its horizontal resizing value to fill container, then how to select the auto layout now and now add a fill color to it to have this now for the padding around items value, I would set it to eight and set the corner radius value to eight, just like this.</p>
<p>Now if I expand this, you'd see that I have this component looking just like this.</p>
<p>And this is okay.</p>
<p>So I want to select it out, name this stock list and out make it a component.</p>
<p>That's fine.</p>
<p>Now the next component I'd like to have there on the InVEST page will be a component that will be used to display the list of stocks that the user have invested literally the stock portfolio of the user.</p>
<p>So I would come here let's zoom in one small out have a 48 by 48 px frim going out, give it a corner radius of 100 to make it around, then I'll give it this color.</p>
<p>Now out, go to the brand fetch plugins, and out, look for the paystack logo, which is this.</p>
<p>Now outcome here, I would right click on this paystack logo, I like to pick out the background color.</p>
<p>So I'll use the Remove BG plugin.</p>
<p>for that.</p>
<p>I'll keep the logo selected, and I'll make it a 24 by 24 px logo, just like this, and I'll place it right at the center of this circular frame that we have created.</p>
<p>Now when you place that on top of that circular frame, make sure to set the constraints value for the horizontal axis to the center and for the vertical axis to the center.</p>
<p>So the next thing to do is to go ahead and I'd say pay stack, I'll keep it selected, come here.</p>
<p>And I'll use the body large bold text for that.</p>
<p>And right under this, paste that text out have plus 345, just to represent the appreciation value of that stock.</p>
<p>So I'll keep it selected and outcome here.</p>
<p>And I'll go with the body small text.</p>
<p>Now I'd make this to have a green color, just like this and for the paste that text and make it to have this color.</p>
<p>So I would select both of these, first of all, create an auto layout, make this space in between items value to be set to four, then out select this text, set it to fill container.</p>
<p>And for this outset to fill container also now out expand this, and that's fine.</p>
<p>Now the next thing to do is to select all of this, create an auto layout on all of them.</p>
<p>When I create an auto layout on this outcome, how to set the spacing between items value to eight, and out add the fill color to that to have this now when I set this to eight outcome here and out set the pattern around items value to eight.</p>
<p>Now I'd like for us to check to see if this is a responsive auto layout.</p>
<p>And as you can see, it's not and that's because I have not set the horizontal resizing value for this auto layout inside of it to feel container.</p>
<p>So when I set this to fill container, and I come here now you'll see that we have a responsive layout.</p>
<p>So I'll keep it selected outcome here.</p>
<p>Now it sets the corner radius value to eight.</p>
<p>And then we have our portfolio listing component.</p>
<p>So I would say portfolio portfolio list.</p>
<p>And I'll click on Create components.</p>
<p>So I think we have created all of the components that we are going to need on our invest page.</p>
<p>So at this stage, I'd like for us to go ahead and create our invest page.</p>
<p>So I would come here now out, select this out, duplicate it out, rename this to invest.</p>
<p>And I'd come here and take all of this out.</p>
<p>And now leave the bottom navigation components, this time around outcome here, what I'd have first will be that cash card.</p>
<p>So I'd have 1234 space before that.</p>
<p>But to see cash card, I'll bring the cash card in here.</p>
<p>And for this cash card, I'll change the fill color of this cash card to this out, select this and I'll change this also to this, I'll change the text color here to this.</p>
<p>And for this, I'll change this to that.</p>
<p>So I'll go ahead now.</p>
<p>And I'll bring in the Assets card.</p>
<p>And I'll do the same to that also come here, I'll change the color of that to this.</p>
<p>And this will be changed to this, change this to this and this to this.</p>
<p>And that's okay.</p>
<p>So what I'll do now is out arrange all of this to stay organized.</p>
<p>So I'd like this to take up two columns.</p>
<p>And I'd like this to come here and take up two columns.</p>
<p>So let's zoom in to be sure that this is properly organized.</p>
<p>So this is not properly organized.</p>
<p>And that's because I want four row spaces before this.</p>
<p>So I will bring this down here.</p>
<p>When I select this, I'd have 1234 And this is okay.</p>
<p>So I'll bring this here.</p>
<p>And I'll bring this down here.</p>
<p>So this is sorted, we have this section sorted.</p>
<p>So the next section of this page will be the section where I would write a text that's going to say top stocks to invest in.</p>
<p>So I would have eight row spaces before this.</p>
<p>So I would say 12345678.</p>
<p>I don't have this to hear.</p>
<p>Now for the text here.</p>
<p>I'd like this text to be a body large text, not a body large bold text.</p>
<p>Now after this text, I'd like to have that search field.</p>
<p>So I would snap this to this point.</p>
<p>And I would go ahead to bring in that search impute field which is this and I'll just have only an eight px space between this text here and the input field.</p>
<p>So out come here stretch these to this point.</p>
<p>And I'll change the placeholder fetch.</p>
<p>So let's change this from stock to stocks.</p>
<p>And that's fine.</p>
<p>So the next component I'd like to have is the stock list components.</p>
<p>So I'll keep this here, and actually give it a shadow effect so that we can see that clearly.</p>
<p>So let's zoom in.</p>
<p>So I would give it two spaces, one, two, and that's fine.</p>
<p>So out, snap this perfectly.</p>
<p>And I would like this stop here.</p>
<p>And I would like this also, to stop here.</p>
<p>Let's zoom out.</p>
<p>So I would duplicate this and have this house.</p>
<p>And let's duplicate this here.</p>
<p>Let's duplicate this hair also.</p>
<p>So let's zoom in to confirm that all our components are aligned perfectly.</p>
<p>So you can see this is okay, this is okay.</p>
<p>This is okay.</p>
<p>And this is okay.</p>
<p>So that looks okay, now on have a stock portfolio section.</p>
<p>Now, to differentiate the two sections out, bring in the button components, and I would use it for something different this time around.</p>
<p>So I would have 1-234-567-8910 1112 spaces.</p>
<p>So I'd have 12 Row spaces here, I would zoom out, out stretch this to the end like this, I would come here and align the content of this button now to the left, then I would set its top padding value to eight and the bottom padding value to eight.</p>
<p>Now what I have here will be stock portfolio.</p>
<p>Now to make this look different, I'll keep this selected, come here now to set the corner reduce value to zero, just like this.</p>
<p>Now what are we going to have here, we are going to have the paste back component here.</p>
<p>So let's zoom in.</p>
<p>And let's make sure this is properly organized.</p>
<p>So I'd have 1234 space before this.</p>
<p>And that's okay, outcome here.</p>
<p>Now give it a shadow effect, just like this now out, keep this selected, come here, now change the color.</p>
<p>So I would come here, I'll change the color to this.</p>
<p>So the green color here needs to actually be thicker than it is now, just like this.</p>
<p>So I would make this to have two columns, then I'll duplicate it and have this they have also taken up two columns also.</p>
<p>Now you can go ahead and have other stocks listed here.</p>
<p>That if you want to have that, and here we are, we are done with our invest page.</p>
<p>Now since we won't be able to display all of the stock portfolio here, I would like to have a see all text here.</p>
<p>So this see all text will be brought in text out copy here.</p>
<p>And I'll duplicate this see all text.</p>
<p>And I keep you here also, and I'll change the color of this, see all text or change this and that's fine.</p>
<p>Now the next flow will be this.</p>
<p>Now let's assume a user likes this talk here and the user wants to invest in this talk means the user will click on the stock and the user will be taken to the stock Details page.</p>
<p>Right.</p>
<p>So let's make that happen.</p>
<p>I'd come here, select this page, and I'll duplicate it, come here and change this to stock details.</p>
<p>And that's fine.</p>
<p>So for the stock Details page, I'll take all of this out and out zoom in, then go to the feather icons plugin to get that icon that signifies going back to the previous page.</p>
<p>And this is it.</p>
<p>I'll get it.</p>
<p>I'll bring it here.</p>
<p>And I'll make sure that this icon is actually inside the stock Details page.</p>
<p>And I'll take this to this point.</p>
<p>And that's sorted out, select the icon vector and I'll change its color to this.</p>
<p>So what do we have here, I like for us to have a title here that's going to say stock details.</p>
<p>And this text should have a headline three bold textile for it.</p>
<p>So I would align it to the center horizontally.</p>
<p>And that's okay, now let's change the color this and that's fine.</p>
<p>So what I'd have here will be a component that I would create, I would just come here, I would have this frame to select it and out create a frame with it like this out set this eight, then out sets the colored this van out sets the color to this than out go to brand fetch to get that logo and out place the logo right on that frame layouts that I just created.</p>
<p>I'll grab it and upload it here.</p>
<p>Now I'd keep it selected and outset the horizontal constraints to center and the vertical constraints to send that and that's okay, so what I'll do now is out keep this frame selected, rename this to stock detail.</p>
<p>And then I'll come here and I'd make it a component.</p>
<p>So I'll go to that page now.</p>
<p>And over here I'd have that stock detailed banner components placed.</p>
<p>This is it here.</p>
<p>I'd have it stay here out stretch it to this point.</p>
<p>and are stretched this this point, that's okay.</p>
<p>So I would come here now, let's snap that in.</p>
<p>And let's also make sure that this is snapped in perfectly, just like this.</p>
<p>So over here I have 123.</p>
<p>Let's make it four.</p>
<p>So over there have four row spaces between this stock details, text, and this stock detail banner components.</p>
<p>And that's fine.</p>
<p>So let's zoom out.</p>
<p>The next thing I'd have here will be the stock price.</p>
<p>And the appreciation value, I'll make sure I have 1234 spaces.</p>
<p>That's okay.</p>
<p>Now I'll go ahead to create a component that outplays here and and that component will go into more details about the stock.</p>
<p>So let's go ahead and let's create that component.</p>
<p>So to create that component outcome here, and now to select the frame to now create a frame that's 42 px tall, just like this.</p>
<p>Let's zoom in to this point.</p>
<p>When I create this frame here, I'll come over here and I'll create a text on this frame, I'd say my position, I'll keep this text here, just like that.</p>
<p>And that's fine.</p>
<p>Now for this text, I'll use the body small textile that I have here, which is this.</p>
<p>And that's okay.</p>
<p>Now I'll go ahead, I'll create another text here, I'll actually make this text box to be this Why'd not come here, now just type in 35.</p>
<p>Now, I'll keep this text box selected now and align the content of that text box to stay at the right select this frame layout now, and then make it an auto layout.</p>
<p>Now I would come here and I'll click on the alignment and padding value, and out sets the left padding to 16 and sets the right padding to 16.</p>
<p>Then out set the top padding to 12 and the bottom padding to 12.</p>
<p>Now I'd like this text to always stay here and this text to always stay here.</p>
<p>So I would come here and now change this from pact to space between.</p>
<p>And that's okay.</p>
<p>So if I come here now, you'd see that if I take this in, this is always staying here.</p>
<p>And this is always staying here.</p>
<p>Same thing happens if I resize the left side here, just like this.</p>
<p>And that's what I want actually.</p>
<p>So I'll keep that selected, then come here.</p>
<p>Now I'm select this text here to make sure this is set to hog content, then come here and select this text to make sure this is set to fixed width.</p>
<p>And that's okay.</p>
<p>So out select this, and out creates an auto layout on this auto layout now, just like this, now this new auto layout is called brim 25.</p>
<p>Yeah.</p>
<p>So inside this new auto layout that I just created, we have this auto layout here, which is frame 24.</p>
<p>Out select it and not duplicate it vertically just like this.</p>
<p>Now select the frame 25 Auto Layout, then I'll set the space between the items inside the auto layout for when I do that, I would come here and now change the padding around items value to zero just to have that now I would come here and I would set the color for this frame 25 auto layout to this.</p>
<p>Now what I'll do is I would set the corner radius value for this auto layout to eight.</p>
<p>Now the corner radius won't be visible.</p>
<p>And that's because this auto layout here is staying on top of that auto layout.</p>
<p>So I would select this auto layout here which is at the top, and I'll come here, I would click on independent corners here.</p>
<p>And I'll set the top left corner reduced value to eight.</p>
<p>And now set the top right corner reduce value to eight, just like this outcome here out select this, click on Independence corners and outset the bottom right corner reduce value to eight and I'll set the bottom left corner reduce value to eight.</p>
<p>And that's sorted.</p>
<p>Now for each of these rows here out select this, then come here and I'll change it horizontal resizing value to fill container.</p>
<p>I'll do that for this also.</p>
<p>Do that for this also.</p>
<p>And do that for this.</p>
<p>And that's okay.</p>
<p>Now let's see if this responding how we actually wanted to respond.</p>
<p>And it is actually now let's edit these values that we have here.</p>
<p>So I would come here and how to set this open and how to set this to previous close and out set this to market cap.</p>
<p>Now for this I'll change the value to So out, come here, previous close out, say that plus this and open, just any value there, actually, just any value, there will be fine, actually.</p>
<p>So with this, I have successfully created these components that allow us to show more details about that stock.</p>
<p>So I would come here and not call this detail table.</p>
<p>Actually, I would call it stock detail table.</p>
<p>And I'll save that, then come here and make it a component.</p>
<p>And here we have that.</p>
<p>So I would zoom out, and I'll go over to this page, and out, bring that component.</p>
<p>So let's come here, click on the Assets tab, come here, grab this and place it here.</p>
<p>So out, keep it selected, and I'll add a shadow effect, just like this, then zoom in so that I can calculate the row spaces better.</p>
<p>So from this item here, I would like to have 123 and four row spaces people this, let's zoom out, and let's stretch this to this point.</p>
<p>And that's fine.</p>
<p>So I can go ahead, select this text, so that I'll be able to change the colors out, select all of this, come here and change this.</p>
<p>To that good, this was not selected.</p>
<p>So I would change that.</p>
<p>For this also out, change it.</p>
<p>Now the next component I'd like to have here will serve as links just in case the user wishes to read more about the stock and the company that owns the stock.</p>
<p>So I'll go ahead, and I'll have that it's going to be similar to what we have here.</p>
<p>Now this is me creating this just the same way I created this stock portfolio components here.</p>
<p>The only difference here is that I just changed the color from what I have here to this.</p>
<p>So let's zoom in to be sure that we are placing our items properly.</p>
<p>So outcome here, I would have 1234 Row spaces before this.</p>
<p>And that's okay.</p>
<p>So at the bottom here, I'd have a button component just for a user who is satisfied with what they see here on this stock Details page.</p>
<p>And this button is going to be an invest button.</p>
<p>So out zooming to calculate the space better.</p>
<p>So I have 123456 Row spaces here.</p>
<p>And I would like to stop at the sixth rule space.</p>
<p>And that's it.</p>
<p>So if a user likes what they see here, on the stock Details page, the user can go ahead and click on the InVEST button.</p>
<p>If the user is not satisfied, the user can come here and click on this button to go back to the previous page where the user will still have to see all the stocks listed here.</p>
<p>So that's it.</p>
<p>So the next page here will be the page that the user will go to, when the user clicks on this invest button here, I'd like us to go ahead and create that page.</p>
<p>So I would duplicate this.</p>
<p>So outcome here, I would rename this to enter stock, amount, whatever you want to call it is okay.</p>
<p>So outcome here, I'll change this to enter amount.</p>
<p>And that's cool.</p>
<p>So I'll go ahead and I'll have this here.</p>
<p>Now this is me using an input field and a button as simple as that.</p>
<p>So I will zoom in to this point and out calculate the space better, I would select this item and out calculates the space from that item, I would say 123456.</p>
<p>So I'd like six rule spaces there.</p>
<p>So I would select this.</p>
<p>And I'll make sure that snaps perfectly.</p>
<p>And that's it.</p>
<p>Now the space between this input field and this button is 1234.</p>
<p>And that's fine.</p>
<p>How to come here.</p>
<p>Now check out this invest button.</p>
<p>And this page is sorted.</p>
<p>Now when the user enters the amount that the user wishes to invest in the stock with, the user will go ahead and click on this Proceed button.</p>
<p>Now when the user clicks on this Proceed button, the user will be taken to another page.</p>
<p>Now that page will be where the user will be presented with a summary of the investment that the user is about make.</p>
<p>Now outcome here.</p>
<p>I would select this and out duplicate it and out.</p>
<p>Rename this to investments summary.</p>
<p>Now I'll zoom in outcome here.</p>
<p>And now take all of these out.</p>
<p>And I'd have this here.</p>
<p>Now this is going to be a summary of the investment that the user is about to make.</p>
<p>And if the user is okay with the summary that the user sees here, then the user would go ahead and enter their secrets been here, before they click on the InVEST button to finally make the investment.</p>
<p>So outcome here out, select all of these, and out calculate the row space is better.</p>
<p>So I would come here, I would keep this here, I would make sure that I have lead zoomin, I'd make sure that I have 123456 Row spaces there.</p>
<p>And that's cool.</p>
<p>So out, zoom out to this point, and this page is sorted.</p>
<p>So this is the flow so far.</p>
<p>Now when the user is on the homepage here, and the user wants to invest, the user will click on this invest link at the bottom navigation here.</p>
<p>This is it here at the bottom navigation here.</p>
<p>When the user clicks on this link, the user will be taken to the InVEST page, which is this.</p>
<p>And if the user goes through the list of stocks that we have here, and the user is interested in investing in one of these stocks, let's say this one here, the user will go ahead to click on it.</p>
<p>And when the user clicks on it, the user will be taken to the stock Details page here, which is this.</p>
<p>Now when the user is taken to this page, the user will read about the stock.</p>
<p>If the user likes what the user sees here, the user will go ahead and click on the InVEST button here.</p>
<p>When the user does that, the user will be taken to this page, where the user will have to enter the amount that the user wishes to invest in that stock with.</p>
<p>Now, when the user enters the amount here, the user will click on the Proceed button here.</p>
<p>When the user does that, then the user will be taken to this page where the user will see a summary of the investments that the user is about to make.</p>
<p>Then if the user is okay with this, the user will go ahead to enter their secrets pin here.</p>
<p>When the user does that, the user will click on the InVEST button here for the investments to be made successfully.</p>
<p>So before we proceed further, I'd like to come here and change this to summary.</p>
<p>So I would keep that selected and align it to the center horizontally, I'd also come here, select these and make sure it's aligned to the center horizontally.</p>
<p>Now, I'll come to this page, which is the Invest page.</p>
<p>And I'd like to have a title here, I'll change this to invest an hour, align it to the center horizontally, just like that.</p>
<p>Now, when the user clicks on this invest button here, the user will see a page that says investment successfully made or investment made or whatever, whatever just a success message.</p>
<p>So I would come here, I would select this, and I'll duplicate it, and I would rename this successful investments.</p>
<p>And I'd save that.</p>
<p>So what I'm going to have here will be similar to what I have here.</p>
<p>So what I'll do is out, take out all that I have here on this page, I'll take this out.</p>
<p>Also, I was supposed to take this out also this debit card title here, I'll take that out.</p>
<p>Also, I'll just select all of this out, duplicate it.</p>
<p>And I bring this in here, just like this.</p>
<p>And I'll zoom in.</p>
<p>And I'll just change this to success.</p>
<p>I'll keep it selected and out, align it to the center horizontally.</p>
<p>Now I'd come here, I'd say go back home.</p>
<p>And that's it.</p>
<p>That's sorted.</p>
<p>So so far.</p>
<p>So so far, we have achieved the authentication task, we have achieved the funding task, and we have achieved the investment task.</p>
<p>Now we are going to go ahead to create more screens that will actually make the user experience on this app to be better.</p>
<p>So one of those screens will be the Transaction Details page.</p>
<p>And that's the page that the user will go to when the user clicks on any of this card here under the recent transactions section.</p>
<p>So if the user clicks on this card, for example, the user will be taken to a page where the user will see the full details of this transaction.</p>
<p>So let's go ahead and let's create that page.</p>
<p>So outcome here out select this one here, and I'll duplicate it.</p>
<p>And I have that.</p>
<p>So let's keep it selected, come here.</p>
<p>And let's call this transaction details.</p>
<p>And for the Transaction Details page, I'll take this out.</p>
<p>And I'll take this out.</p>
<p>Now this is what I would have on this transaction details page.</p>
<p>This is it's as simple as this.</p>
<p>So first things, first, let's calculate our row space to be sure that it's perfectly set.</p>
<p>So I'll have this here and out Count 123456.</p>
<p>So I like this to start here 123456 Out, snap this correctly, and out snap this correctly.</p>
<p>And that's okay.</p>
<p>So this here is to display the transaction date that that transaction happened.</p>
<p>So this is not complete, actually, I can give some space here and say 1603, just like that, so that we will depict the date and time of the transaction.</p>
<p>And that's cool.</p>
<p>Now, what we have here is the transaction amount.</p>
<p>And here we have the amount in words, here we have the transaction type, which is a withdrawal, here we have the transaction remark, which is for Netflix, and the status of that transaction is successful.</p>
<p>So I would select all of this zoom in.</p>
<p>And I would make sure I have 1234 photo spaces there.</p>
<p>Now for the button components here, how to select this, and I'll make sure I have 123456, I'll make sure I have six row spaces there.</p>
<p>And that's fine.</p>
<p>So if a user comes here, and the user clicks on one of these transactions, the user will go to a transaction details page, where the user will see more details about that transaction.</p>
<p>So I'll go ahead and out create other pages, that's going to make the experience on this app to be better.</p>
<p>Now, before we do that, I'd like to give this transaction details page, a page title.</p>
<p>So out, duplicate this, and I'll bring you here a lot call that transaction details out, align it to the center horizontally, just like this.</p>
<p>And that's fine.</p>
<p>So the next flow that I'd like to design will be the flow that the user will go to when the user clicks on this menu icon here.</p>
<p>Now when the user clicks on this menu icon, I'd like for a menu bar to slide in with other options that the user can use to improve their experience on this app.</p>
<p>So how do we make that happen? It simply, so outcome here, I'd have an iPhone 13 Promax, here, out, rename this to manage slide bar, and out, keep it selected, come here, and I would divide the width by two, just like this.</p>
<p>And I'd have this.</p>
<p>So I might decide to go ahead and increase this further.</p>
<p>And what I'll do is this outcome here, I'll just have the logo here.</p>
<p>And I would go ahead to have list items of menu links.</p>
<p>So the first menu link, I would have here will be recent transactions.</p>
<p>I'll keep that selected here.</p>
<p>And I'll change this to a body small text just like this.</p>
<p>Now let's zoom in.</p>
<p>Let's keep this here.</p>
<p>I'll keep it selected, and I would create an auto layout on that text.</p>
<p>Now this auto layout, I would like the auto layout to have a padding around items value of 16.</p>
<p>And I'd also like the alignment value to be set to the left.</p>
<p>So I would come here now I would keep this then creates another auto layout on top of it.</p>
<p>Now this new auto layout that I have created will have a padding around items value of zero, just like this.</p>
<p>Now outcome here out expand this new auto layout here in the design tree.</p>
<p>When I do that out, select the recent transactions auto layout, and I'll duplicate it just like this.</p>
<p>Now go ahead to edit all of these two other links.</p>
<p>Before I do that, let's select the main Auto Layout now, which is frame 34.</p>
<p>Here, and let's set the spacing between items value two, four, just to have that.</p>
<p>So the next link here will be card management, I'd have this be investment portfolio.</p>
<p>I would have this be request statement.</p>
<p>And I'd have this be settings and that's fine.</p>
<p>But I would come here I would select all of these text.</p>
<p>And I'll change the color to this.</p>
<p>And that's what we have.</p>
<p>So whenever the user clicks on On this menu icon, this is going to slide out from the left.</p>
<p>And that's okay.</p>
<p>So let's go ahead to create the routes that the users will go to when the users click on this transact link here at the bottom navigation section.</p>
<p>So to do that, I would come here, I would select this here, and I will duplicate it.</p>
<p>I would rename that to transact, without zooming out, come here.</p>
<p>And I would say, transact.</p>
<p>Keep that selected and out, align that to the center horizontally, then I'll take all of these outs.</p>
<p>Now, I'd like to have two card components here, one for withdrawal action, and one for a deposit action, as simple as that.</p>
<p>So let's go ahead and let's create those card components.</p>
<p>So outcome here out, create a text here, I'll just say deposits.</p>
<p>And I'll keep this text selected.</p>
<p>Come here, and I'll go with the headline three bold text, just like this.</p>
<p>Now, I'd come here and I'd have a 48 by 48 px frame layout, with a corner reduce of 100, then I'd come here and I'll give it a color, that's green, then go to be further icon slogan.</p>
<p>And I'll get an incoming icon there, which is this, this is our incoming arrow icon out, place this here, then come here and set the constraints value to center and center.</p>
<p>Now out, select the icon vector, and now change the color to this.</p>
<p>So I would bring this here, select this, and then create an auto layout on it.</p>
<p>Now for this auto layout, I would come here and I'd set the alignment property to center.</p>
<p>When I do that, I'd come here and outset the space in between items value to 16, then go ahead to add a fill color.</p>
<p>When I add the fill color out, come here and I'll set the padding around items value to eight.</p>
<p>To have that then I would go ahead to set the corner reduce value to eight.</p>
<p>Now outcome here now select the deposit text and change the horizontal resizing value from hog content to fill container.</p>
<p>So this is the deposit action card that I would have on that page.</p>
<p>outcome here, I would rename this to deposit action, save that, and then come here and click on Create components.</p>
<p>Now select this text and I'll change the color to this.</p>
<p>Now I would come here now I would go to this page.</p>
<p>And I would bring in VAT components.</p>
<p>This is it.</p>
<p>I'll keep it selected.</p>
<p>And I'll give it a shadow effect out zoom into this point.</p>
<p>I'll bring this here.</p>
<p>And I'd make sure I have 123456 Row spaces.</p>
<p>And that's okay.</p>
<p>So out stretch this to this point like this.</p>
<p>And I'll create a component or withdrawal.</p>
<p>I'll duplicate this component, which is the master component, take notes.</p>
<p>And I would detach instance, when I detach instance out, select the circular frame there out, make this red out, select the arrow frame there, and I would set the rotation value to 180 degrees.</p>
<p>And that's sorted, as easy as that.</p>
<p>So I would come here select it's come here and go to the design three and rename this to withdraw action.</p>
<p>When I do that, I'll keep it selected.</p>
<p>And I'll click on Create components here.</p>
<p>And that's okay.</p>
<p>So outcome here now, I'll bring this in give it a shadow effect, like this, I would have this day here.</p>
<p>And I would spread this to this point.</p>
<p>And that's okay.</p>
<p>So finally, on this page, I would love to have a button here that can be used to perform the adding of card action.</p>
<p>So I would keep this here I'd have 16 px margin space here, which is to row spaces.</p>
<p>One and two are keep the bottom selected.</p>
<p>out, set the top padding value to eight and the bottom padding value to eight.</p>
<p>Then I'll change the text contents there to add card just like that.</p>
<p>And that's sorted.</p>
<p>So this is the page that the users will go to when the users click on this transact link here at the bottom Navigation component.</p>
<p>So this is where I would stop for this project in regards to creating screens and outs stop here because we have achieved the actual user task for this app.</p>
<p>Now I'd like you to take this as your own assignments and and when you are done.</p>
<p>You can Tagami tweets on Twitter, my Twitter handle is you can go ahead and tag me to your assignment on Twitter.</p>
<p>Now, the assignment is this, I'd like you to have a notifications icon here.</p>
<p>And the notification icon should take users to a page of notifications when they click on it.</p>
<p>And the notifications can be anything.</p>
<p>It can be newsletters, it can be transaction notifications, it can be anything at all.</p>
<p>Now place the notification icon here and create a Notifications page that users will go to when the user clicks on the notification icon.</p>
<p>Now, after that, come here and create a route or create a page that the user will go to when the user select add another card, create a page that the user can use to add their debit card details to this app.</p>
<p>The third assignment will be this, come here and create a page that the user can use to request for their statement.</p>
<p>After that, create a settings page now on this settings page, lets the user be able to set their secrets been there.</p>
<p>Now over here, which is the card management link, the user should be able to delete a card that they have added to this app, or add another card that they want to add to this app.</p>
<p>So that should be possible when the user clicks on card management here.</p>
<p>This should take the user to a page where they will be able to see all the cards that they have on this app.</p>
<p>And and also, they should have the ability on that page to add and delete cards.</p>
<p>Now take notes, this Add Card button here should take the user to the same page that you would create for this add another card here, just like that.</p>
<p>And also, this recent transactions link here should take the users to a dedicated page for the list of all recent transactions.</p>
<p>This investment portfolio link here should take the user to a dedicated page of all the investments that the user has made on this app.</p>
<p>So go ahead to build all of those pages, so that you can have a full and complete user experience.</p>
<p>Now, finally, for the assignment, just before I forget, come here and create a Forgot Password page, create a page here that the user can use to reset their password just in case the user forgets their password.</p>
<p>And that's going to be it.</p>
<p>So at this stage, what we are going to do is to create a prototype of all of these designs that we have created, we are going to link this perfectly and see how it's going to work.</p>
<p>So to do that, let's zoom in out come here, I will start from the splash screen.</p>
<p>So I would select it.</p>
<p>Come here click on prototype.</p>
<p>When I click on prototype, I would come here and I would connect the splash screen to this page.</p>
<p>Now the action will be an on tap action.</p>
<p>And that's because this is a mobile app actually.</p>
<p>So we are actually supposed to tap this screen with our fingers.</p>
<p>Now when the user taps on the screen, the user should move to or should navigate to, you can see the action here should navigate to the author selection page, which is this.</p>
<p>Now the transition animation or the navigation animation should be a smart animation.</p>
<p>So it's going to be an ease in animation.</p>
<p>And I would like this ease in animation to be for 800 milliseconds.</p>
<p>Actually, I'd like this to be an ease in and out animation, just like this.</p>
<p>Yeah, that's better for me.</p>
<p>So outcome here now.</p>
<p>And I will say okay, when the user clicks on the login button here, the user should go to the login page.</p>
<p>And I'll keep all of the sets the way it is.</p>
<p>Now when the user clicks on the get started button here, the user should go to the signup page.</p>
<p>So I would come here, click on this login button here.</p>
<p>And I would say when the user clicks on that login button after after passing in their email address and password, the user should go to the homepage, which is this over here.</p>
<p>When the user clicks on the signup button, the user should go to the verification page where the user will have to enter the verification code sent to their phone numbers.</p>
<p>Now when the user types in the verification code here, the user should click on the Verify button.</p>
<p>And when the user clicks on the Verify button, this should show like a pop up so I would connect it to this.</p>
<p>So out connect this And I'd keep it as on top, then for the action out habit set to open overlay, then come here and I'll keep it sets a centered actually, after setting these two Centered Outcome here, and I won't select this option.</p>
<p>And that's because I don't want the user to close the pop up.</p>
<p>If they mistakenly click outside the pop, I'd like the user to click on proceed here.</p>
<p>So this other option here out selected, this is the add background behind overlay property or the add background behind overlay option.</p>
<p>When I select it, it means that when the popup shows up, the background will be faded.</p>
<p>So I would set the Opacity value to 35%.</p>
<p>And I would like the animation to be an instant animation.</p>
<p>And that's going to be okay.</p>
<p>Now, when the user clicks on this Proceed button, the user should be taken to the homepage.</p>
<p>Now, when you are creating a prototype like this, you can just take the connection here to any page at all, then come here and set it to the page you want to set it to.</p>
<p>So I would come here and I would select Home.</p>
<p>And you can see that the connection has gone to the homepage, just like this.</p>
<p>So the authentication is set.</p>
<p>Now when the users come to the homepage, and the users click on this menu icon, the user should be taken to the menu, slide bar them here, this is what should show up when the user clicks on that menu icon.</p>
<p>Now, I would want that menu slide bar or that slide bar menu to actually slide in from the left.</p>
<p>So I'll click on this connection here to have the Interaction Details page show up.</p>
<p>Now for the action here, I would set these to open overlay outcome here and I'll set it to manual.</p>
<p>When I set it to manual, it means I'll be the one to set how the interaction is going to happen.</p>
<p>So I'll grab this, and I'll place this here, just like this.</p>
<p>This is how it's going to look like when you click on that menu icon.</p>
<p>Now outcome here.</p>
<p>And I would say close this slide by menu, when the user clicks outside of it, I would select that and over here out have a background behind overlay properties selected, also an out have the Opacity value set to 35%.</p>
<p>Now for the animation, I'll change this from instance, to move in just like this.</p>
<p>And for the moving action out habits moving from the left and out have the speed of that animation set to 800 milliseconds.</p>
<p>Now outcome here, I'll click on this font Account button here.</p>
<p>And I'd say okay, when a user clicks on this button, this should show us a pop up.</p>
<p>So we all know how to set a pop up, right.</p>
<p>So I'll change this to open overlay.</p>
<p>Keep it set centered, and out add a background behind overlay action.</p>
<p>And also, if the user chooses not to fund the account anymore, the user can just click outside the pop up and go back to the homepage.</p>
<p>So I would select that.</p>
<p>I'll keep this set to 35%.</p>
<p>And for the animation here, I'll keep it set instance.</p>
<p>So I'll close this.</p>
<p>Now if the user selects the bank transfer option, the user should come here, as easy as that.</p>
<p>And if the user clicks on copy account number, this account number will be copied to the user's clipboard.</p>
<p>And when that happens, the user will come here and click on this arrow here to go back to the homepage out sets this from instant to smart animates.</p>
<p>And that's okay.</p>
<p>So if the user clicks on the debit card option here, the user would be taken to this page.</p>
<p>If the user is taken to this page, and the user types in the amounts that they are trying to actually fund the account with, then the user will go ahead to tap or to click on the fund account button here.</p>
<p>And when the user does that, the user would come to this page where the user will have a message that says account funded successfully.</p>
<p>Now, at this stage, we are going to want the user to go directly to the InVEST page.</p>
<p>So I'll select this button now.</p>
<p>And I'll take this flow to the InVEST page, which is this.</p>
<p>So when the user gets here, I'll take this menu icon out here actually, when the user gets here, and the user wants to invest in one of these listed stocks, let's say this one, the user will click on it and the user will be taken to the stock Details page.</p>
<p>When the user gets to the stock Details page and the user is okay with all of these details here.</p>
<p>The user will click On the InVEST button here.</p>
<p>And when the user does that, the user will come here and be required to enter the amounts that they wish to invest in that stocks with.</p>
<p>When the user enters the amount and the user clicks on the Proceed button, the user will be taken to this page, which is where the user will see a summary of the investment that the user is about to make.</p>
<p>Now, if the user is satisfied with this summary, the user will go ahead to type in their secrets pin here, and then click on this invest button.</p>
<p>And when the user does that, the user will be taken to this page, which is a success page, that's going to let the user know that, hey, you have successfully invested in that stock.</p>
<p>So the user will come here and click on the Go back home button, and out, take this back to the homepage, how to select home here.</p>
<p>So let's come here, let's see the other links that we have not created.</p>
<p>So let's say the US is trying to see the transaction detail of any of this recent transaction.</p>
<p>Yeah, let's see the withdrawal transaction here, I would click on it to select it.</p>
<p>And I would link this to the Transaction Details page, which is this.</p>
<p>So if the user clicks on that transaction card, there, the user will be taken to this page.</p>
<p>And if the user goes through the whole detail, and the user is satisfied, when the user clicks on done, the user will go back to the homepage, outcome here and select home here.</p>
<p>Same will happen if the user comes here, clicks on that arrow, the user will go back to the home page.</p>
<p>So you can see that we are creating lots of connections and flows here.</p>
<p>Lots of connections and flows here.</p>
<p>So let's go back to the homepage, and let's see the flow that we have not created.</p>
<p>So this is the home page here.</p>
<p>So this home link here is safe to be there.</p>
<p>Now let's say the user clicks on this invest link here, which is in the bottom navigation components, the user should be taken to the InVEST page.</p>
<p>If the user clicks on this transact link here, the user should be taken to the transact page.</p>
<p>So if I come here, now out still connect this, this should go to the homepage.</p>
<p>And since this is the Invest page here, it means we are here.</p>
<p>So this should go to the transact page.</p>
<p>I'll do that for this also.</p>
<p>So let's come here.</p>
<p>Let's see, let's see what we have not connected yet.</p>
<p>So if the user comes to the transact page, and the user clicks on the deposits card here, the user should have that pop up, show up, that would require them to select if they want to deposit with bank transfer or their debit card, it should be the same flow.</p>
<p>Now over here, I should actually change this to withdraw.</p>
<p>If the user clicks on this withdraw card here, the user should be taken to a page where they would have to enter the amount and the destination bank that they are trying to withdraw their funds to.</p>
<p>So this is also going to be a part of your assignment.</p>
<p>Go ahead and create that flow.</p>
<p>When you create it.</p>
<p>Go ahead and tag me on Twitter for my comment.</p>
<p>So let's go ahead and let's present this flow.</p>
<p>And let's see how it's going to look like.</p>
<p>So I would come here, I would select the splash screen.</p>
<p>And I'd come here and click on present.</p>
<p>So when I click on present, I would have the splash screen show up here.</p>
<p>When I click on it, I would have the option to either login or get started.</p>
<p>So I'll click on get started.</p>
<p>And here we are on the signup form page.</p>
<p>So if the user enters their email address, phone number and password when the user clicks on the signup button, the user will be required to enter the verification code.</p>
<p>When the user enters that the user will click on the Verify button here.</p>
<p>And a pop up will show up here saying phone number verified.</p>
<p>Now you'll see that when I click outside the pop up, the pop up won't go away until I come here and I click on the Proceed button.</p>
<p>When I do that, I'll be taken to the homepage.</p>
<p>Now here we are in the homepage.</p>
<p>Now if I come here and I click on this menu icon here, you will see that this menu slide bar or this slide bar menu and how you call it is fine.</p>
<p>This slide by menu slides in from the left.</p>
<p>When I click outside of it, it goes back in.</p>
<p>Now let's check the font accounts flow.</p>
<p>When I click on it, I would have this pop up show up here that says Select method.</p>
<p>Now let's say I choose to select the bank transfer method, I would have this show up here, I'd be able to copy the account number.</p>
<p>And when I'm done, I would come here and I would click on this arrow icon here.</p>
<p>To go back to the homepage.</p>
<p>Now let's click on the bond Account button once more, and let's select the debit card method, you can see that I'll be taken to this page where I would have to enter the amount that I'm trying to fund this account with.</p>
<p>Now, let's say I type in the amount, I would come here and I'll click on the fund account button, just like this.</p>
<p>And I'd have this message that says accounts funded successfully.</p>
<p>Now if I go ahead and click on this invest button, I'll be taken to the InVEST page, which is this.</p>
<p>And over here, I would see a list of stocks.</p>
<p>Now I'd like to present this in full screen actually, so that we can see better.</p>
<p>So over here, I would see a list of stocks that I can invest in.</p>
<p>Now let's say I'd like to invest in this one here, I would click on it.</p>
<p>And I would see full details about this stock here.</p>
<p>Now, I don't have some of my components showing here.</p>
<p>So I would go back to my design outcome here.</p>
<p>So this is the stock Details page.</p>
<p>So this three buttons actually not inside that layout.</p>
<p>So I would select the three of them.</p>
<p>And I'll take them inside that layout.</p>
<p>And that sorted.</p>
<p>Now when I come back here, you will see that I have that here.</p>
<p>So let's go back to our full screen presentation.</p>
<p>So if the user likes what they see here in the stock Details page, the user will go ahead to click on the InVEST button here.</p>
<p>And when the user does that, the user will enter the amount that they would like to invest in that stocks with.</p>
<p>When the user does that, the user will go ahead to click on the Proceed button here.</p>
<p>Now that flow is not created.</p>
<p>So I would come back to our design here, I would click on this Proceed button here, click on prototype.</p>
<p>And now let's see what the problem is.</p>
<p>So I came here and I clicked on this connection link here.</p>
<p>And I changed this from on drag to on top.</p>
<p>Now when I come back here, and I click on the Proceed button here, you will see that we are taken to the Summary page.</p>
<p>Now this page will be the page where the user will see a summary of the investments that the user is about to make.</p>
<p>And if the user is OK with this, the user will go ahead to enter their secrets pin here and then click on the InVEST button.</p>
<p>Now the InVEST button is not active also outcome here and out see the problem for that.</p>
<p>So I would click on invest here.</p>
<p>And I would select the connection flow here.</p>
<p>And as you can see here, there is an undo drag event here, outcome here.</p>
<p>And I'll delete that on drag event here.</p>
<p>And I'll just leave this set to tap now.</p>
<p>But the tap event, there is no navigation destination.</p>
<p>So I would set this.</p>
<p>First of all out to take note of the screen here.</p>
<p>This is the successful investment page.</p>
<p>So I would come here and I would go to the successful investment page.</p>
<p>And that's sorted.</p>
<p>Now when I come here, and I click on invest, I'd be taken to the success page.</p>
<p>Now when I click on Go back home, I'll be taken back to the homepage.</p>
<p>Now that is after I have successfully invested in a stock.</p>
<p>Now, what happens if I come here, and I click on one of the recent transactions here, let's say the withdrawal transaction here, you would see that I'll be taken to the transaction details page for that transaction.</p>
<p>When I'm done going through it out, click on Done.</p>
<p>And I'll be taken back to the homepage.</p>
<p>Now what's going to happen if I come here and I click on this invest link at the bottom navigation components.</p>
<p>I'll be taken to the InVEST page still.</p>
<p>And I'd be able to still invest in a stock just like this.</p>
<p>Now what happens if I come here and I click on the transact link here or be taken to this page where I'd have the option to deposit funds or withdraw funds.</p>
<p>And I'd also have the option to Add Card.</p>
<p>Now if I am okay with this outcome here, and I'll click on this arrow to go back to the homepage and that arrow is not active.</p>
<p>So I would have that sorted out come here and connect that arrow to be homepage and it's going to be an on tap event.</p>
<p>So when I come back here, when I click on that arrow now, you will see that I'm taken back to the homepage.</p>
<p>So go ahead, create the order pitches and the other route as your assignment, then tag me to it on Twitter.</p>
<p>So that's that for this course.</p>
<p>If you found this cost to be helpful, go ahead, click on the subscribe button, leave a comment in the comment section.</p>
<p>And stay tuned for more content.</p>
<p>Thank you and see you in another course. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ UX Designer Salary – How much do UX/UI Designers Make? Entry Level Range ]]>
                </title>
                <description>
                    <![CDATA[ If you are new to tech, you might have just discovered UI/ UX design and want to pursue that career path. But what is the starting salary for entry level UX/UI designers? In this article, I will provide definitions for UI/ UX design as well as starti... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ux-designer-salary-how-much-do-ux-ui-designers-make-entry-level-range/</link>
                <guid isPermaLink="false">66b8da568cd1c2aa053d49bd</guid>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Fri, 15 Oct 2021 17:39:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/daniel-korpai-bOKIptPzdPk-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are new to tech, you might have just discovered UI/ UX design and want to pursue that career path. But what is the starting salary for entry level UX/UI designers?</p>
<p>In this article, I will provide definitions for UI/ UX design as well as starting salary information from around the world. </p>
<h2 id="heading-what-is-ux-design">What is UX design?</h2>
<p>The term User Experience refers to how users interact with a product or service. Whenever you login into a website, or play a game on your phone, your interaction with that application is considered user experience.</p>
<p>If you find a product to be easy to use and understand, then that would be considered a positive user experience. But if the product is confusing and frustrating then that would be considered a negative user experience.</p>
<p>If you want to learn more about UX design, and find resources to start learning, then I would suggest reading my article on <a target="_blank" href="https://www.freecodecamp.org/news/user-experience-design-what-does-a-ux-designer-do/">What is UX Design?</a></p>
<h2 id="heading-what-is-ui-design">What is UI design?</h2>
<p>The term User Interface refers to the look and feel of a product. For digital products, UI design focuses on all visual aspects including fonts, colors, spacing, responsive design and more. </p>
<p>Good UI design is considered to be simple, easy to understand and consistent. You don't want users to have to struggle with navigating through the product because it is not intuitive. </p>
<p>Bad UI design is considered to be inconsistent and difficult to understand. If users are confronted with low quality images, inconsistent fonts or poor contrast in visual content, then the user will want to leave the product as soon as possible.</p>
<p>If you are interested in learning the fundamentals of UI design, then I would suggest reading through <a target="_blank" href="https://www.freecodecamp.org/news/learn-ui-design-fundamentals-with-this-free-one-hour-course/">this Per Harald Borgen article</a>. </p>
<h2 id="heading-resources-to-start-learning-uiux-design">Resources to start learning UI/UX design</h2>
<p>Here is a list of resources to learn UI/UX design.</p>
<ul>
<li><a target="_blank" href="https://www.coursera.org/learn/foundations-user-experience-design?specialization=google-ux-design">Foundations of User Experience (UX) Design</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=_Hp_dI0DzY4">The 2019 UI Design Crash Course for Beginners</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=3q3FV65ZrUs">Figma Tutorial – A Free UI Design/Prototyping Tool</a></li>
<li><a target="_blank" href="https://www.uxpin.com/studio/ebooks/">UXpin: Free UX Ebooks</a></li>
</ul>
<h2 id="heading-salaries-around-the-world-for-uiux-designers">Salaries around the world for UI/UX designers</h2>
<p>In this section, I will show you some salaries from around the around for entry level UI/UX designers. </p>
<h3 id="heading-united-states">United States</h3>
<p>This data was pulled from indeed.com, payscale.com, and ZipRecruiter. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.14.02-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.14.26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.19.05-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This data represents the national average. If you want data for your specific city, then you can search for that in these job sites. </p>
<h3 id="heading-canada">Canada</h3>
<p>This data was pulled from ZipRecruiter. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.28.02-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.28.13-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-mexico">Mexico</h3>
<p>This data was pulled from payscale.com and is in MXN currency.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.35.20-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-uk">UK</h3>
<p>This data was pulled from uk.talent.com. The average entry level salaries for UI/UX designers would start at £35,000. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screen-Shot-2021-10-15-at-7.46.23-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-other-countries-around-the-world">Other Countries around the world</h3>
<p>If you want to explore other UX salaries from around the world, you can look into <a target="_blank" href="https://uxdesignersalaries.com/">https://uxdesignersalaries.com/</a> </p>
<p>You can also use popular job sites in your area, to find out the average entry level salary for UI/UX designers. </p>
<p>I hope you enjoyed this article and best of luck on your UI/UX journey.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ UI/UX Design Guide: What Are UI Designers, and How Are They Different Than UX Designers? ]]>
                </title>
                <description>
                    <![CDATA[ Have you noticed how User Interface and User Experience design are considered different topics nowadays?  You're not the only one. We live in a beautiful era of design, with new techniques and trends coming and going. Frontend development is also gai... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ui-ux-design-guide/</link>
                <guid isPermaLink="false">66c375aef278f15f931a3422</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alexandru Paduraru ]]>
                </dc:creator>
                <pubDate>Tue, 13 Jul 2021 02:14:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/cover.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you noticed how User Interface and User Experience design are considered different topics nowadays? </p>
<p>You're not the only one.</p>
<p>We live in a beautiful era of design, with new techniques and trends coming and going. Frontend development is also <a target="_blank" href="https://2020.stateofcss.com/en-US/">gaining increased momentum</a>, with more and more developers getting involved in UI/UX design.</p>
<p>While both UI and UX design are often placed on the same pedestal, they are fundamentally different, and beginners should understand the difference between the two.</p>
<p>Knowing this, my team from <a target="_blank" href="https://creative-tim.com">Creative Tim</a> and I have done a lot of research and created a comprehensive guide on the most important parts of these two huge domains:</p>
<ol>
<li><a class="post-section-overview" href="#heading-ui-design-how-things-look"><strong>UI Design — How Things Look</strong></a></li>
<li><a class="post-section-overview" href="#heading-ux-design-how-things-work"><strong>UX Design — How Things Work</strong></a></li>
<li><a class="post-section-overview" href="#heading-what-are-the-key-differences-between-ui-and-ux-design"><strong>What Are the Key Differences Between UI and UX Design?</strong></a></li>
<li><a class="post-section-overview" href="#heading-what-do-uiux-designers-do"><strong>What Do UI/UX Designers Do?</strong></a></li>
<li><a class="post-section-overview" href="#heading-what-are-the-disadvantages-of-a-combined-uiux-role"><strong>What Are the Disadvantages of a Combined UI/UX Role?</strong></a></li>
<li><a class="post-section-overview" href="#heading-how-do-uiux-designers-work-together"><strong>How Do UI/UX Designers Work Together?</strong></a></li>
<li><a class="post-section-overview" href="#heading-what-are-the-salaries-of-ui-and-ux-designers"><strong>What Are the Salaries of UI and UX Designers?</strong></a></li>
<li><a class="post-section-overview" href="#heading-how-do-you-become-a-ui-or-ux-expert-what-kind-of-design-coursestutorials-should-you-take"><strong>How Do You Become a UI or UX Expert? What Kind of Design Courses/Tutorials Should You Take?</strong></a></li>
<li><a class="post-section-overview" href="#heading-which-should-you-specialize-in-ui-or-ux-design"><strong>Which Should You Specialize In? UI or UX Design?</strong></a></li>
</ol>
<h2 id="heading-ui-design-how-things-look"><strong>UI Design — How Things Look</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/quote-martin-leblac-1.jpg" alt="Image with the quote &quot;A User interface is like a joke. If you have to explain it, it's not that good.&quot; — Martin LeBlac" width="600" height="400" loading="lazy"></p>
<p>A UI (User Interface) deals with the application's graphical layout, which includes buttons, screen layout, animations, transitions, micro-interactions, and so on. In short, UI is all about how things look.</p>
<p>UI design includes the following formats:</p>
<ul>
<li><strong><a target="_blank" href="https://en.wikipedia.org/wiki/Graphical_user_interface">Graphical User Interface (GUI)</a></strong>: GUI design involves how users interact with the visuals and digital control panels of a system. The computer's desktop is an example of a GUI.</li>
<li><strong><a target="_blank" href="https://en.wikipedia.org/wiki/Voice_user_interface">Voice-controlled Interface (VUI)</a></strong>: VUI design deals with the interaction between a user and a system using voice. Smart assistants like Bixby for Samsung mobile devices and Siri for iPhones are examples of VUIs.</li>
<li><strong><a target="_blank" href="https://en.wikipedia.org/wiki/Gesture_recognition">Gesture-based Interface</a></strong>: This is mostly used in virtual reality (VR) and other gesture-based design scenarios, which deal with the engagement of users within 3D spaces. Here is an example of our fully coded simulation of the <a target="_blank" href="https://www.creative-tim.com/product/soft-ui-dashboard-pro">Soft UI Admin Dashboard</a> in VR:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/soft-vr-2-1.gif" alt="Example of a gesture-based interface." width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://demos.creative-tim.com/soft-ui-dashboard-pro/pages/dashboards/default.html">Source</a></em></p>
<p>For good UI design, you should take these characteristics into consideration:</p>
<ul>
<li>The design should be focused on helping users complete tasks quickly with minimum effort. Completing tasks should be a seamless experience.</li>
<li>It should be enjoyable, satisfactory, and free from frustration.</li>
<li>The UI design should communicate the brand value of the company/organization.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/10-design-pinciples-1.jpg" alt="A list of principles for good design." width="600" height="400" loading="lazy"></p>
<h2 id="heading-ux-design-how-things-work"><strong>UX Design — How Things Work</strong></h2>
<p>UX (User Experience) design deals with how users interact with the system. Logical navigation and how smooth and intuitive the experience is all fall under UX design. In short, this type of design helps users have a positive experience.</p>
<p>To get a feeling of the UX process, here are the main steps:</p>
<ul>
<li><strong>Interaction Design</strong> deals with how users can complete their tasks effortlessly by using the interactive components of a system (page transitions, animations, buttons, and so on).</li>
<li><strong>User Research</strong> involves conducting extensive research, collecting feedback and ideas from new or existing customers, understanding end user needs, and making design decisions based on these parameters.</li>
<li><strong>Information Architecture</strong> involves the organization of information and content that users need to do their tasks. This requires a UX designer to understand the relationship between different sets of content and present them in the most understandable way possible.</li>
</ul>
<p>For good UX design, you should follow these practices:</p>
<ul>
<li>The product should be easily usable, logical, and self-explanatory.</li>
<li>The product should solve users's problems.</li>
<li>The product should be accessible and usable to a wide range of people.</li>
<li>The product should create a positive experience for the user, allowing them to complete tasks without frustration.</li>
</ul>
<h3 id="heading-cognitive-biases"><strong>Cognitive Biases</strong></h3>
<p>Great UX designers must be aware of the cognitive biases that we all have, as this can affect the interaction between the user and interfaces. Many marketing strategies are based on these biases:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Cognitive_bias_codex_en.svg" alt="A codex of cognitive biases" width="600" height="400" loading="lazy">
_<a target="_blank" href="https://upload.wikimedia.org/wikipedia/commons/6/65/Cognitive_bias_codex_en.svg">Source</a>_</p>
<h2 id="heading-what-are-the-key-differences-between-ui-and-ux-design"><strong>What Are the Key Differences Between UI and UX Design?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/ui-vs-ux-1.jpg" alt="Image of a branching walking path and dirt path." width="600" height="400" loading="lazy"></p>
<p>UI and UX design have often been used as interchangeable terms.</p>
<p>While the end product requires consideral input from both design methodologies, the process of designing UI and UX is very different.</p>
<p>UX design mostly deals with the user’s entire journey to solve a problem. </p>
<p>On the other hand, UI design is focused on how the product looks and feels when the problem is being solved.</p>
<p>Here are the main differences between UI and UX design:</p>
<ul>
<li><strong>Main focus:</strong> The main focus of UI designers is to deal with the quality and visuals of the end product, and use hi-fi models as prototypes. UX designers focus more on the purpose and functionality of the end product, and care more about logic. Additionally, UI designers deal with the technicalities of the product design, while UX designers focus more on project management and analysis of the project.</li>
<li><strong>Use of color:</strong> UI designers design prototypes in full color while UX designers do so in black, white, or grey.</li>
<li><strong>Tools:</strong> UI designers use tools like <a target="_blank" href="https://www.sketch.com/">Sketch</a>, <a target="_blank" href="https://www.flinto.com/">Flinto</a>, <a target="_blank" href="https://principleformac.com/">Principle</a>, and <a target="_blank" href="https://www.invisionapp.com/">InVision</a> for collaborative image designing. UX designers use wireframe-based prototyping tools like <a target="_blank" href="https://www.mockplus.com/">Mockplus</a>.</li>
<li><strong>Artistic Component:</strong> UI designers have to include an artistic component in their design since it is related to what the end user sees, hears, and feels. UX design has more of a social component, as it needs to understand what a user wants to experience in the end product.</li>
</ul>
<p>Here is an example of UX and UI prototypes for the same end product:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/soft-ui-design-system-1.jpg" alt="A simple UX design wireframe and a hi-fi UI prototype for the same web page." width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.creative-tim.com/product/soft-ui-design-system-pro">Source</a></em></p>
<h2 id="heading-what-do-uiux-designers-do"><strong>What Do UI/UX Designers Do?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/table-1.jpg" alt="A table showing the differences between UI and UX designers." width="600" height="400" loading="lazy"></p>
<p>If you want to become a greate <strong>UI designer</strong>, you should develop the following skills/responsibilities:</p>
<ul>
<li>Working in agile teams.</li>
<li>Creating user flows, wireframes, prototypes and so on.</li>
<li>Visualization tools such as <a target="_blank" href="https://www.invisionapp.com/">InVision</a>,<a target="_blank" href="https://www.sketch.com/"> Sketch</a>,<a target="_blank" href="https://www.photoshop.com/"> Photoshop</a>,<a target="_blank" href="https://www.figma.com/"> Figma</a>, etc. For more details about which tool to choose, check out our research in this article: <a target="_blank" href="https://www.freecodecamp.org/news/adobe-xd-vs-sketch-vs-figma-vs-invision/">InVision vs Sketch vs Figma vs Photoshop</a></li>
<li>Frontend programming languages such as HTML5, CSS3, and JavaScript.</li>
<li>Executing visual design stages from inception to final hand-off.</li>
<li>Collaborating with UX designers, developers, QA, and product managers to design and implement innovative visual ideas for products.</li>
<li>Communicating the branding and style of the company to users through design.</li>
<li>Creating the look and feel of the product using customer analysis and research.</li>
<li>Managing the responsiveness, interactivity, and animation of a product and making it adaptive to all device screen sizes.</li>
</ul>
<p>If you want to become a great <strong>UX designer</strong>, you should develop these skills/responsibilities:</p>
<ul>
<li>Working in agile teams.</li>
<li>A strong understanding of the UX process.</li>
<li>Prototyping tools like <a target="_blank" href="https://www.adobe.com/creativecloud.html">Adobe Creative Suite</a>, <a target="_blank" href="https://www.sketch.com/">Sketch</a>,<a target="_blank" href="https://www.invisionapp.com/"> InVision</a>, <a target="_blank" href="https://www.axure.com/">Axure</a>, etc.</li>
<li>Problem solving skills and curiosity about everything related to design, people, life and technology.</li>
<li>Stakeholder management and client interaction.</li>
<li>Creating process flows, wireframes, sitemaps, prototypes, and UX deliverables.</li>
<li>Collaborating closely with developers, product managers, UI designers, external stakeholders, and QA Engineers to iterate designs based on market dynamics, user feedback, and tech constraints.</li>
<li>Analyzing customer needs, competitors, product structure, and strategies for designing the experience of a product.</li>
<li>Creating seamless design and interaction strategies for mobile, web, desktop, and other hardware endpoints.</li>
</ul>
<h2 id="heading-what-are-the-disadvantages-of-a-combined-uiux-role"><strong>What Are the Disadvantages of a Combined UI/UX Role?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Artboard--4--1.jpg" alt="A concept seat belt design from the 1960s which went around people's necks." width="600" height="400" loading="lazy"></p>
<p>Having a combined UI/UX role is almost like wearing two different hats at the same time.</p>
<p>While most organizations advertize a UI/UX role as a single, combined role, a UI and UX designers have different skill sets. Their main focus, way of thinking, and method of prototyping a product differ greatly.</p>
<p>A combined UI/UX role requires constant switching between conceptualization and visualization, which is often difficult and can reduce the amount of attention that each discipline requires.</p>
<h2 id="heading-how-do-uiux-designers-work-together"><strong>How Do UI/UX Designers Work Together?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Artboard-Copy-4--1--1.jpg" alt="Designers working together." width="600" height="400" loading="lazy"></p>
<p>While UI design and UX design require very different skill sets, they are both important components that must work in harmony to give the best experience to end users.</p>
<p>A UI design might be beautiful, but it can be clunky and confusing to navigate without a good UX design. On the other hand, the user experience of a product can be flawless, but it is nothing without a good looking user interface.</p>
<p>Any frontend development and design process should start with understanding the needs of the user. UX and UI designers should work in collaboration with other developers, managers, and product owners to understand what the end product should be able to do, how it should feel, and what it should look like.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/quote-steve-jobs-1.jpg" alt="A quote from Steve Jobs that reads, &quot;Design is not just what it looks like and feels like. Design is how it works.&quot;" width="600" height="400" loading="lazy"></p>
<p>UX designers are generally involved in the earlier phases of a product design since they need to design the flow of activities that take place when a user needs to solve a problem. This involves analytic and project management activities.</p>
<p>Later, a UI designer builds on the aesthetics and interactions based on the models provided by the UX designer.</p>
<p>Given this, it is safe to state that UX and UI go hand in hand. And while there are instances when the same person does both, one design principle cannot exist without the other.</p>
<h2 id="heading-what-are-the-salaries-of-ui-and-ux-designers"><strong>What Are the Salaries of UI and UX Designers?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/ux-salary-1.jpg" alt="A map showing different UI/UX designer salaries in different parts of the world." width="600" height="400" loading="lazy"></p>
<p>UI designers earn an average of 50k worldwide, with the average salary in the USA being 91k, Germany being 57k, France being 47k, and 67k in the UK.</p>
<p>UX designers earn slightly more, with an average of 52k worldwide. UX designers in the US earn 102k on average, with Germany paying 53k, 49k in France, and 68k in the UK. (Source: <a target="_blank" href="http://www.glassdoor.com/">Glassdoor</a>)</p>
<p>Note: All the salaries listed above are an average for the area, and are in USD.</p>
<h2 id="heading-how-do-you-become-a-ui-or-ux-expert-what-kind-of-design-coursestutorials-should-you-take"><strong>How Do You Become a UI or UX Expert? What Kind of Design Courses/Tutorials Should You Take?</strong></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/tutorials--1--1.jpg" alt="Animated people using laptops." width="600" height="400" loading="lazy"></p>
<p>Becoming a UI or UX expert starts with being genuinely interested in UI/UX design. Once you know you're interested, you should find resources and take design courses that help prepare you for the job market.</p>
<p>There are online courses like the <a target="_blank" href="https://careerfoundry.com/en/courses/become-a-ui-designer/">UI Design Program</a> and <a target="_blank" href="https://learnui.design/">Learning UI Design</a> that can help you kickstart your journey towards becoming a UI designer.</p>
<p>For UX design, you can study online,<a target="_blank" href="https://www.interaction-design.org/courses"> paid courses</a>, or courses from<a target="_blank" href="https://online.rmit.edu.au/course/sc-user-experience-design-dtr105"> online universities</a>. You can also look at the<a target="_blank" href="https://uxplanet.org/30-best-online-course-websites-to-learn-ui-ux-updated-6b104762731a"> best online course websites to learn UI/UX</a> so you can see which websites offer courses for free and the user feedback on these websites.</p>
<p>For UX design, there are a number of <a target="_blank" href="https://www.interaction-design.org/courses">paid courses</a>, of courses from <a target="_blank" href="https://online.rmit.edu.au/course/sc-user-experience-design-dtr105">online universities</a>. You can also check out a list of the <a target="_blank" href="https://uxplanet.org/30-best-online-course-websites-to-learn-ui-ux-updated-6b104762731a">best online courses to learn UI/UX design</a> so you can see which websites offer courses for free, and read user feedback.</p>
<p>Suppose you already have some of the required skills to be a UI/UX designer. In that case, you can also take a look at articles like the <a target="_blank" href="https://uxdesign.cc/10-essential-cognitive-behavior-patterns-for-ux-design-7f0cc2e00d31">behavior patterns for UX design</a>, <a target="_blank" href="https://uxdesign.cc/65-ux-methods-and-when-to-use-them-73e70c742d12">UX methods that you can use</a>, <a target="_blank" href="https://dribbble.com/tags/article">inspirational graphic designs from the world's best designers</a>, and <a target="_blank" href="https://uxdesign.cc/5-academic-research-papers-every-designer-should-read-f24b170db295">academic research papers that designers should read</a>.</p>
<h3 id="heading-which-should-you-specialize-in-ui-or-ux-design"><strong>Which Should You Specialize In? UI or UX Design?</strong></h3>
<p>Specializing in UI or UX design is a personal preference that depends on your particular skillset. </p>
<p>However, there are a huge number of companies that advertise a combined UI/UX designer role. </p>
<p>While the roles and responsibilities of both these vary differently, there is still a niche market for UI/UX design, making it a good idea to have adequate knowledge about both.</p>
<p>While difficult to implement, a combined UI/UX career can prove fruitful in terms of salary compensation and importance in the company.</p>
<p>However, a combined UI/UX designer role is difficult to perform since it needs constant switching from one mindset to the other. So it is often a better option to specialize in one role instead.</p>
<p>For example, if you are artistic, know effective color combinations, and understand how products can be visually enhanced, UI design is a good choice for you.</p>
<p>On the other hand, if you are good with managing user and stakeholder needs, have excellent analysis skills, and understand how user experiences can be improved, UX design would be more suited to you.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/quote-joe-sparano-1.jpg" alt="A quote from Joe Sparano that reads, &quot;Good design is obvious. Great design is transparent.&quot;" width="600" height="400" loading="lazy"></p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>User Interface and User Experience design both require an understanding of what users need.</p>
<p>Once you have this understanding, frontend development and design do not have to be a complex affair — there are a lot of ready-made components, tools, and kits that can make design easier and more effective.</p>
<p><a target="_blank" href="https://www.creative-tim.com/">Creative Tim</a> offers you a huge number of free and premium, fully coded UI tools like Templates, Dashboards, and Design Systems.</p>
<p>If you want to build your illustrations using hand-drawn sketch components in a scalable manner, look no further than Creative Tim’s product: <a target="_blank" href="https://iradesign.io/">IRA Design</a>.</p>
<p>And let's keep in touch on <a target="_blank" href="https://twitter.com/CreativeTim">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Design an iMessage-like Chat Bubble in React Native ]]>
                </title>
                <description>
                    <![CDATA[ By Prajwal Kulkarni Whether you're an Apple fan or not, you'll likely agree that Apple sure does have a groundbreaking UI. And iMessage is definitely an important part of that design.  The curved arrow is something that I have always really liked and... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/design-imessage-like-chat-bubble-react-native/</link>
                <guid isPermaLink="false">66d4608be39d8b5612bc0deb</guid>
                
                    <category>
                        <![CDATA[ app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Chat ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Mar 2021 18:50:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/feature_image_freecodecamp-3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Prajwal Kulkarni</p>
<p>Whether you're an Apple fan or not, you'll likely agree that Apple sure does have a groundbreaking UI. And iMessage is definitely an important part of that design. </p>
<p>The curved arrow is something that I have always really liked and have wanted to replicate for a long time.</p>
<p>After a lot of trial and error, I was finally able to find a workaround to build a similar version of iMessage's chat bubble. In this article, I'll take you through the steps required to build a chat bubble that looks like Apple's iMessage.</p>
<p>If you're building a chat application or intending to display information in the form of a message, I'd definitely recommend that you try out this style as it makes your app look cool and professional.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>This article assumes that you know the basics of:</p>
<ul>
<li>JSX </li>
<li>React Native </li>
<li>HTML &amp; CSS</li>
</ul>
<h2 id="heading-what-is-a-chat-bubble">What is a Chat Bubble?</h2>
<p>A chat bubble is basically a container that holds text. Chat bubbles are mostly used in Instant Messaging apps to display chat logs effectively. </p>
<p>The conventional method is that sent messages are displayed on the right side of the screen and received messages are shown on the left, with different colors used to differentiate between sent and received message(s).</p>
<p>Most messaging apps have a basic chat bubble which is a regular container with rounded corners. The main differentiating factor between other apps and iMessage is the presence of a small curved-like arrow anchoring the text container, which looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/freecodecamp-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-build-a-chat-bubble-that-looks-like-imessage">How to Build a Chat Bubble that Looks like iMessage</h2>
<p>If we look at the above image carefully, we can see that the iMessage chat bubble is a combination of a regular chat bubble with an added arrow in the corner.</p>
<p>The main challenge lies in tying the arrow to the text container.</p>
<p>Before directly hopping into the code, I'd want you to know how this arrow-like element is created and added.</p>
<p>First, check out <a target="_blank" href="https://codepen.io/samuelkraft/pen/Farhl">this</a> code, which shows how to implementation this arrow using HTML &amp; CSS. Below is its code snippet.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">255px</span>;
  <span class="hljs-attribute">word-wrap</span>: break-word;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">12px</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">24px</span>;
  <span class="hljs-attribute">position</span>: relative;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span> <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">25px</span>;

  &amp;:before, &amp;:after {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">""</span>;
        <span class="hljs-attribute">position</span>: absolute;
    <span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">25px</span>;
  }
}

<span class="hljs-selector-class">.from-me</span> {
    <span class="hljs-attribute">color</span>: white; 
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#0B93F6</span>;
    <span class="hljs-attribute">align-self</span>: flex-end;

    &amp;:before {
        <span class="hljs-attribute">right</span>: -<span class="hljs-number">7px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#0B93F6</span>;
        <span class="hljs-attribute">border-bottom-left-radius</span>: <span class="hljs-number">16px</span> <span class="hljs-number">14px</span>;
    }

    &amp;<span class="hljs-selector-pseudo">:after</span> {
        <span class="hljs-attribute">right</span>: -<span class="hljs-number">26px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">26px</span>;
    <span class="hljs-attribute">background-color</span>: white;
        <span class="hljs-attribute">border-bottom-left-radius</span>: <span class="hljs-number">10px</span>;
    }
}
<span class="hljs-selector-class">.from-them</span> {
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#E5E5EA</span>;
    <span class="hljs-attribute">color</span>: black;
  <span class="hljs-attribute">align-self</span>: flex-start;

    &amp;:before {
        <span class="hljs-attribute">left</span>: -<span class="hljs-number">7px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#E5E5EA</span>;
        <span class="hljs-attribute">border-bottom-right-radius</span>: <span class="hljs-number">16px</span>;
    }

    &amp;<span class="hljs-selector-pseudo">:after</span> {
        <span class="hljs-attribute">left</span>: -<span class="hljs-number">26px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">26px</span>;
    <span class="hljs-attribute">background-color</span>: white;
        <span class="hljs-attribute">border-bottom-right-radius</span>: <span class="hljs-number">10px</span>;
    }
}
</code></pre>
<p>If you just browse straight through the code it might seem quite awful. So let's break it down at an atomic level and later glue it all back together.</p>
<p>The <code>&lt;**p&gt;**</code> tag includes style constraints such as margin-bottom, position, padding and so on. Note that the max-width used here is 255px, which is a static value. But we'll be using a dynamic approach, as the chat bubbles need to be responsive across various screen sizes.</p>
<p>The <code>&amp;:before</code> and <code>&amp;:after</code> within the <strong><code>&lt;p&gt;</code></strong> style defines two elements with no content in it. They're positioned absolute with respect to the <strong><code>&lt;p&gt;</code></strong> tag (text container), and are placed at the bottom. They have a height of 25px (the height of the arrow).</p>
<p>Going further, the <code>.from-me</code> (sent messages) style defines that the text be white, background blue (#0b936f), and that it's placed at the right side of the screen (align-self: flex-end). </p>
<p>Now comes the important part – extending the <strong><code>&amp;:before</code></strong> and <strong><code>&amp;:after</code>,</strong> which is the actual implementation of the arrow.</p>
<p>The <strong><code>&amp;:before</code></strong> has a width of 20px and is placed at 7 pixels negative to the right. It has a border-bottom-left radius of 16px, which is what gives the curved look to the arrow.</p>
<p>Similarly, the <strong><code>&amp;:after</code></strong> has a width of 26px and is placed at 26 pixels negative to the right. Since -7px &gt; -26px, <code>&amp;:after</code> is placed right side of the <code>&amp;:before</code> element and partially overlaps it.</p>
<p>If you still feel confused, don't worry – just refer to the images below to gain a clearer insight into what I've been talking about.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/fcc1.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>&amp;:before with black background and bottom-left-radius</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/fcc2.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>&amp;:after overlapping &amp;:before with green background</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/fcc3.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>&amp;:after background changed to white to match the background of the chat screen.</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/fcc4.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>&amp;:before background updated to #0b93f6 to match chat bubble color.</em></p>
<p>So basically the arrowhead is created by overlapping two elements at the bottom corner of the chat bubble and adjusting the background colors to match those of the chat bubble and chat screen.</p>
<p>Further ahead, the translation of CSS and HTML into JSX is fairly simple, as most of the things are quite straightforward.</p>
<h2 id="heading-how-to-build-the-react-native-version">How to Build the React Native Version</h2>
<p>Before starting, I want to note that this works best with FlatList, and I recommend that you use it, and not other components or functions such as map (which lacked consistency across different screens and devices). </p>
<p>The three steps we're going to follow here are:</p>
<ol>
<li>Create chat bubble with arrow head</li>
<li>Add styles to chat bubble and arrow head</li>
<li>Embed chat bubble in FlatList</li>
</ol>
<p>So let's get started.</p>
<p>First, we'll create the chat bubble with the arrow head, like this:</p>
<pre><code>&lt;View style={{
                    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#0078fe"</span>,
                    <span class="hljs-attr">padding</span>:<span class="hljs-number">10</span>,
                    <span class="hljs-attr">marginLeft</span>: <span class="hljs-string">'45%'</span>,
                    <span class="hljs-attr">borderRadius</span>: <span class="hljs-number">5</span>,
                    <span class="hljs-comment">//marginBottom: 15,</span>
                    <span class="hljs-attr">marginTop</span>: <span class="hljs-number">5</span>,
                    <span class="hljs-attr">marginRight</span>: <span class="hljs-string">"5%"</span>,
                    <span class="hljs-attr">maxWidth</span>: <span class="hljs-string">'50%'</span>,
                    <span class="hljs-attr">alignSelf</span>: <span class="hljs-string">'flex-end'</span>,
                    <span class="hljs-comment">//maxWidth: 500,</span>

                    <span class="hljs-attr">borderRadius</span>: <span class="hljs-number">20</span>,
                  }} key={index}&gt;


                    <span class="xml"><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">16</span>, <span class="hljs-attr">color:</span> "#<span class="hljs-attr">fff</span>", }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>{item.text}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span></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.rightArrow}</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></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.rightArrowOverlap}</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span>



&lt;/View&gt;


<span class="hljs-comment">//Recevied Message</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">{{</span>
                    <span class="hljs-attr">backgroundColor:</span> "#<span class="hljs-attr">dedede</span>",
                    <span class="hljs-attr">padding:10</span>,
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">5</span>,
                    <span class="hljs-attr">marginTop:</span> <span class="hljs-attr">5</span>,
                    <span class="hljs-attr">marginLeft:</span> "<span class="hljs-attr">5</span>%",
                    <span class="hljs-attr">maxWidth:</span> '<span class="hljs-attr">50</span>%',
                    <span class="hljs-attr">alignSelf:</span> '<span class="hljs-attr">flex-start</span>',
                    //<span class="hljs-attr">maxWidth:</span> <span class="hljs-attr">500</span>,
                    //<span class="hljs-attr">padding:</span> <span class="hljs-attr">14</span>,

                    //<span class="hljs-attr">alignItems:</span>"<span class="hljs-attr">center</span>",
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">20</span>,
                  }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>



                      <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">16</span>, <span class="hljs-attr">color:</span> "#<span class="hljs-attr">000</span>",<span class="hljs-attr">justifyContent:</span>"<span class="hljs-attr">center</span>" }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span> {item.text}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</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.leftArrow}</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">{styles.leftArrowOverlap}</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>&gt;</span></span>
</code></pre><p>The Outermost <strong><code>&lt;View&gt;</code></strong> tag acts as the 'p' tag in comparison with the HTML version. The remaining two <strong><code>&lt;View&gt;</code></strong> tags act as <code>&amp;:before</code> and <code>&amp;:after</code>.</p>
<p>Next, we'll add styles to the chat bubble and arrow head like this:</p>
<pre><code><span class="hljs-keyword">const</span> styles = StyleSheet.create({
<span class="hljs-attr">rightArrow</span>: {
  <span class="hljs-attr">position</span>: <span class="hljs-string">"absolute"</span>,
  <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#0078fe"</span>,
  <span class="hljs-comment">//backgroundColor:"red",</span>
  <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">25</span>,
  <span class="hljs-attr">bottom</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">borderBottomLeftRadius</span>: <span class="hljs-number">25</span>,
  <span class="hljs-attr">right</span>: <span class="hljs-number">-10</span>
},

<span class="hljs-attr">rightArrowOverlap</span>: {
  <span class="hljs-attr">position</span>: <span class="hljs-string">"absolute"</span>,
  <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#eeeeee"</span>,
  <span class="hljs-comment">//backgroundColor:"green",</span>
  <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">35</span>,
  <span class="hljs-attr">bottom</span>: <span class="hljs-number">-6</span>,
  <span class="hljs-attr">borderBottomLeftRadius</span>: <span class="hljs-number">18</span>,
  <span class="hljs-attr">right</span>: <span class="hljs-number">-20</span>

},

<span class="hljs-comment">/*Arrow head for recevied messages*/</span>
<span class="hljs-attr">leftArrow</span>: {
    <span class="hljs-attr">position</span>: <span class="hljs-string">"absolute"</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#dedede"</span>,
    <span class="hljs-comment">//backgroundColor:"red",</span>
    <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">25</span>,
    <span class="hljs-attr">bottom</span>: <span class="hljs-number">0</span>,
    <span class="hljs-attr">borderBottomRightRadius</span>: <span class="hljs-number">25</span>,
    <span class="hljs-attr">left</span>: <span class="hljs-number">-10</span>
},

<span class="hljs-attr">leftArrowOverlap</span>: {
    <span class="hljs-attr">position</span>: <span class="hljs-string">"absolute"</span>,
    <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#eeeeee"</span>,
    <span class="hljs-comment">//backgroundColor:"green",</span>
    <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">35</span>,
    <span class="hljs-attr">bottom</span>: <span class="hljs-number">-6</span>,
    <span class="hljs-attr">borderBottomRightRadius</span>: <span class="hljs-number">18</span>,
    <span class="hljs-attr">left</span>: <span class="hljs-number">-20</span>

},
})
</code></pre><p>Then we'll embed it into FlatList:</p>
<pre><code>&lt;FlatList
        <span class="hljs-comment">//inverted</span>
        style={{<span class="hljs-attr">backgroundColor</span>:<span class="hljs-string">"#eeeeee"</span>}}
        data={<span class="hljs-built_in">this</span>.state.chat_log}
        ref={<span class="hljs-function"><span class="hljs-params">ref</span> =&gt;</span> (<span class="hljs-built_in">this</span>.FlatListRef = ref)} <span class="hljs-comment">// assign the flatlist's ref to your component's FlatListRef...</span>


        renderItem = {<span class="hljs-function">(<span class="hljs-params">{item,index}</span>)=&gt;</span>{

          rowId={index}

            <span class="hljs-keyword">if</span> (SENT_MESSAGE) { <span class="hljs-comment">//change as per your code logic</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">{{</span>
                    <span class="hljs-attr">backgroundColor:</span> "#<span class="hljs-attr">0078fe</span>",
                    <span class="hljs-attr">padding:10</span>,
                    <span class="hljs-attr">marginLeft:</span> '<span class="hljs-attr">45</span>%',
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">5</span>,

                    <span class="hljs-attr">marginTop:</span> <span class="hljs-attr">5</span>,
                    <span class="hljs-attr">marginRight:</span> "<span class="hljs-attr">5</span>%",
                    <span class="hljs-attr">maxWidth:</span> '<span class="hljs-attr">50</span>%',
                    <span class="hljs-attr">alignSelf:</span> '<span class="hljs-attr">flex-end</span>',
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">20</span>,
                  }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>


                    <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">16</span>, <span class="hljs-attr">color:</span> "#<span class="hljs-attr">fff</span>", }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span> {item.text}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</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.rightArrow}</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">{styles.rightArrowOverlap}</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>&gt;</span></span>
                )




            } <span class="hljs-keyword">else</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">{{</span>
                    <span class="hljs-attr">backgroundColor:</span> "#<span class="hljs-attr">dedede</span>",
                    <span class="hljs-attr">padding:10</span>,
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">5</span>,
                    <span class="hljs-attr">marginTop:</span> <span class="hljs-attr">5</span>,
                    <span class="hljs-attr">marginLeft:</span> "<span class="hljs-attr">5</span>%",
                    <span class="hljs-attr">maxWidth:</span> '<span class="hljs-attr">50</span>%',
                    <span class="hljs-attr">alignSelf:</span> '<span class="hljs-attr">flex-start</span>',
                    //<span class="hljs-attr">maxWidth:</span> <span class="hljs-attr">500</span>,
                    //<span class="hljs-attr">padding:</span> <span class="hljs-attr">14</span>,

                    //<span class="hljs-attr">alignItems:</span>"<span class="hljs-attr">center</span>",
                    <span class="hljs-attr">borderRadius:</span> <span class="hljs-attr">20</span>,
                  }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>



                      <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">16</span>, <span class="hljs-attr">color:</span> "#<span class="hljs-attr">000</span>",<span class="hljs-attr">justifyContent:</span>"<span class="hljs-attr">center</span>" }} <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span> {item.text}<span class="hljs-tag">&lt;/<span class="hljs-name">Text</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.leftArrow}</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">{styles.leftArrowOverlap}</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>&gt;</span></span>
                )


            }



        }

        keyExtractor={<span class="hljs-function">(<span class="hljs-params">item,index</span>)=&gt;</span>index.toString()}
        /&gt;
</code></pre><p>Values such as <strong>borderRadius, padding, margin,</strong> and <strong>backgroundColor</strong> are arbitrary values and can be changed if you wish. So feel free to play around and make those changes to best fit your requirements.</p>
<p>The result of the above code looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/IMG_20210324_160111.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Chat bubble appearance, as tested on several devices(Android).</em></p>
<p>Looks cool, doesn't it ? ;)</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You've built a chat bubble that looks just like the one iMessage uses.</p>
<p>I hope you found this article helpful. If so, do share it with your friends and colleagues.</p>
<p>Still have questions? Don't hesitate to get in touch with me, and I'll respond to you as soon as possible.</p>
<p>You could also connect with me on <a target="_blank" href="https://in.linkedin.com/in/prajwal-kulkarni">LinkedIn</a> / <a target="_blank" href="https://instagram.com/prajwalkulkarni_">Instagram</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Style and Theme an App With Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will learn how to style and theme an application in Jetpack Compose. Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system. While still in beta ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-style-and-theme-an-app-with-jetpack-compose/</link>
                <guid isPermaLink="false">66d460cb47a8245f78752abd</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 22 Mar 2021 13:48:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6054c45f687d62084bf67e41.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will learn how to style and theme an application in Jetpack Compose.</p>
<p>Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system.</p>
<p>While still in beta release as of writing this article, I do not expect this particular part of the library to change drastically for the stable release.</p>
<p>Topics include:</p>
<ul>
<li><p>A brief recap of the XML approach</p>
</li>
<li><p>How to migrate from the XML-based colors, themes, and typography (font) system</p>
</li>
<li><p>How to set up light and dark themes for your apps in only a few lines of code</p>
</li>
<li><p>How to use your new Kotlin-based style information in your composables</p>
</li>
<li><p>How to style Text Composables specifically</p>
</li>
</ul>
<p>Before proceeding, it is important that you understand what a composable is. I will not be stopping to explain that concept here, as I already have in <a target="_blank" href="https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/">this article</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/81r-vwPxlaw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-we-used-to-style-android-apps-using-xml-resources">How We Used to Style Android Apps Using XML Resources</h2>
<p>As usual, I like to share with you the motivations behind, and a bit of history on, these topics. In case you do not care, feel free to skip to the next section where we get into the practical stuff.</p>
<h3 id="heading-android-resources">Android Resources</h3>
<p>The Android app resources system is something which the Android team deserves a high five for, at least in my opinion. But like every design decision, a feature in one situation becomes a flaw in another situation.</p>
<p>To be specific, one of the greatest challenges for both platform and application developers alike is to create what I will call <strong>localized resources</strong>. I am referring to the challenge of building apps which:</p>
<ul>
<li><p>Display text and graphics in a variety of different languages and alphabets</p>
</li>
<li><p>Look and feel proportionate to a wide variety of form factors (dimensions, densities, and so on.)</p>
</li>
</ul>
<p>Those are just two common examples – there are plenty more. The resource system gives us a place where app developers can provide localized resources which the platform can select for at compile time. This saves us having to write that boilerplate code ourselves.</p>
<h3 id="heading-feature-or-flaw">Feature or Flaw?</h3>
<p>While I would never want to manage the boilerplate code necessary for localized string resources myself, that does not mean I enjoy writing XML.</p>
<p>In fact, <strong>there are very few things I would prefer to do in XML</strong> over a modern, idiomatic, and elegant language such as Kotlin or Swift. Personal preference aside, there is a more technical reason why XML resources are not always ideal.</p>
<p>Please note that this is not meant as a criticism of the platform developers/engineers. It is merely an observation of how design decisions always have benefits and costs.</p>
<p>In order to integrate our XML-based resources into our JVM-based application code, we must necessarily have <strong>layers of translation</strong> (compilation) and <strong>platform bridges</strong> (APIs). This can present difficulties for both platform and application developers.</p>
<p>Two common problems I ran into were:</p>
<ul>
<li><p>I want access to a resource in a place where I do not want tight coupling to the platform APIs which provide the resource</p>
</li>
<li><p>I have to write some ridiculous boilerplate code just to change the look of a View (that is, override something defined within resource styles and themes)</p>
</li>
</ul>
<p>The <strong>root problem</strong> for everyone involved is <strong>tight coupling</strong> to the View system and the Android resource system (which are themselves tightly coupled together).</p>
<p>For the platform developers, this means they have to build on top of, or work around gigantic and old codebases. Add that they must also try to have new features work on older Android OS versions, and that becomes a very thankless job.</p>
<p>The result for us application developers is most often a lot of <strong>boilerplate code,</strong> some <strong>hacky workarounds</strong> for things which intuitively seem like they should be one-liners. Not to mention the main API for getting these resources is <code>Context</code>, which is a class you really do not want to leak in memory.</p>
<p><strong>Enter Jetpack Compose.</strong></p>
<h2 id="heading-how-to-set-up-themes-colors-and-fonts-with-jetpack-compose">How to Set Up Themes, Colors, and Fonts with Jetpack Compose</h2>
<p>With our review of the old system out of the way, let's explore a much prettier and simpler way to style and theme an Android application. I said I would keep this practical, but allow one point.</p>
<p>Since we will be doing that work in Kotlin, it means one very important thing: Both we and the platform developers are much less bound by translation (compilation) and API bridges (Android's <code>R</code> class and <code>Context</code>) between XML and the JVM.</p>
<p>In simple terms, this means <strong>much less boilerplate code</strong>, and <strong>much more control at runtime</strong>.</p>
<p>For the practical part of this article, my suggestion to you is to follow this process in the order I explain it. I have structured it in the order I follow when writing this code in a new App.</p>
<h3 id="heading-how-to-replace-colorsxml-resources-with-kotlin-compose">How to Replace Colors.xml Resources with Kotlin Compose</h3>
<p>If you have not already decided upon a color scheme for your application, I suggest that you use the various resources available on the official Material Design website. Try out:</p>
<ul>
<li><p>The <a target="_blank" href="https://material.io/design/color/the-color-system.html#tools-for-picking-colors">color palettes</a></p>
</li>
<li><p>The <a target="_blank" href="https://material.io/resources/color/">color tool</a></p>
</li>
</ul>
<p>If you plan to support light and dark app themes (explained shortly), try to select a color scheme which supports white text and a color scheme which supports black text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/color_text_palettes.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of light and dark color schemes.</em></p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Color.kt">Color.kt</a> (the name does not matter) and fill it with immutable <strong>val</strong>ues:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">val</span> primaryGreen = Color(<span class="hljs-number">0XFF00bc00</span>)
<span class="hljs-keyword">val</span> primaryCharcoal = Color(<span class="hljs-number">0xFF2b2b2b</span>)
<span class="hljs-keyword">val</span> accentAmber = Color(<span class="hljs-number">0xFFffe400</span>)

<span class="hljs-keyword">val</span> textColorLight = Color(<span class="hljs-number">0xDCFFFFFF</span>)
<span class="hljs-keyword">val</span> textColorDark = Color(<span class="hljs-number">0xFFf3f3f3</span>)
<span class="hljs-keyword">val</span> gridLineColorLight = Color.Black
<span class="hljs-comment">//...</span>
</code></pre>
<p>You can either use a predefined value like <code>Color.Black</code> or supply your own ARGB Hex value.</p>
<p>Since ARGB Hex is just a bunch of jargon to describe what the heck "<code>0XFF00bc00</code>" means, let me translate:</p>
<ul>
<li><p>First two characters <code>0x</code> tell the compiler that this is a hexadecimal number</p>
</li>
<li><p>Second two characters , "<code>FF</code>" or "<code>DC</code>", represent Transparency/Opaqueness/<strong>A</strong>lpha in Hex</p>
</li>
<li><p>The remaining six character pairs represent <strong>R</strong>ed, <strong>G</strong>reen, and <strong>B</strong>lue</p>
</li>
</ul>
<h3 id="heading-how-to-add-fonts-and-replace-the-fontfamily-attribute">How to Add Fonts and Replace the <code>fontFamily</code> Attribute</h3>
<p>Typography (fonts) is also very easy to manage. This is the kind of thing where Kotlin's <a target="_blank" href="https://kotlinlang.org/docs/functions.html#default-arguments">default arguments</a> are very useful.</p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Type.kt">Type.kt</a> (the name still does not matter) and create <code>Typography</code> class...:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> typography = Typography(
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">16</span>.sp
    ),

    button = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = <span class="hljs-number">32</span>.sp
    ),

    caption = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">12</span>.sp
    )
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>...and some <code>TextStyle</code> classes:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//...</span>
<span class="hljs-keyword">val</span> mainTitle = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Light,
    fontSize = <span class="hljs-number">48</span>.sp,
    textAlign = TextAlign.Center
)

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">dropdownText</span><span class="hljs-params">(color: <span class="hljs-type">Color</span>)</span></span> = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Normal,
    fontSize = <span class="hljs-number">32</span>.sp,
    textAlign = TextAlign.Center,
    color = color
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>Whether you provide public functions or values (I advise against using <code>**var**</code> here) is up to your individual preference and current requirements.</p>
<h3 id="heading-how-to-create-an-app-theme-in-jetpack-compose">How to Create an App Theme in Jetpack Compose</h3>
<p>The last thing you need to configure before using your theme in your composables is a <code>MaterialTheme @Composable</code>. I have mine, and along with my light and dark color palettes in a file called <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/GraphSudokuTheme.kt">GraphSudokuTheme</a>:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.foundation.isSystemInDarkTheme
<span class="hljs-keyword">import</span> androidx.compose.material.MaterialTheme
<span class="hljs-keyword">import</span> androidx.compose.material.darkColors
<span class="hljs-keyword">import</span> androidx.compose.material.lightColors
<span class="hljs-keyword">import</span> androidx.compose.runtime.Composable
<span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> LightColorPalette = lightColors(
    primary = primaryGreen,
    secondary = textColorLight,
    surface = lightGrey,
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,
    onSurface = accentAmber
)

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> DarkColorPalette = darkColors(
    <span class="hljs-comment">//main background color</span>
    primary = primaryCharcoal,
    <span class="hljs-comment">//used for text color</span>
    secondary = textColorDark,
    <span class="hljs-comment">//background of sudoku board</span>
    surface = lightGreyAlpha,
    <span class="hljs-comment">//grid lines of sudoku board</span>
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,

    onSurface = accentAmber

)

<span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">GraphSudokuTheme</span><span class="hljs-params">(
    darkTheme: <span class="hljs-type">Boolean</span> = isSystemInDarkTheme()</span></span>,
    content: <span class="hljs-meta">@Composable</span> () -&gt; <span class="hljs-built_in">Unit</span>
) {

    MaterialTheme(
        colors = <span class="hljs-keyword">if</span> (darkTheme) DarkColorPalette <span class="hljs-keyword">else</span> LightColorPalette,
        typography = typography,
        shapes = shapes,
        content = content
    )
}
</code></pre>
<p>Since you should already be familiar with what a composable is (I gave you fair warning), the only new thing here is <code>darkTheme: Boolean = isSystemInDarkTheme()</code>.</p>
<p>To give a simplified explanation, <code>isSystemInDarkTheme()</code> is a call which asks any compatible Android device for the user's preference of a light or dark theme.</p>
<p>It <strong>returns a boolean value</strong> which we can use in a Ternary (Conditional) Assignment expression such as <code>colors = if (darkTheme) DarkColorPalette else LightColorPalette</code>.</p>
<p>That is actually it. Colors, Fonts, and two Themes defined in a few minutes.</p>
<h2 id="heading-how-to-use-a-theme-in-compose">How to Use a Theme in Compose</h2>
<p>It is now time to use this Theme in your app. In this app, which only has two primary screens, I just use an <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/activegame/ActiveGameActivity.kt">Activity</a> as a <strong>container</strong> for my composables:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">class</span> NewGameActivity : AppCompatActivity(), NewGameContainer {
    //...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //...

        setContent {
            GraphSudokuTheme {
                NewGameScreen(
                    onEventHandler = logic::onEvent,
                    viewModel
                )
            }
        }
        //...
    }
</code></pre>
<p>Wherever you find yourself calling <code>setContent {}</code>, my suggestion for beginners is to immediately place your Theme composable inside of it. Doing so will cause the style information to <strong>cascade/inherit to each nested composable</strong>.</p>
<p>You are done! Almost.</p>
<h2 id="heading-how-to-override-styles-and-themes">How to Override Styles and Themes</h2>
<p>If you can help it, try to include any colors you will want in your light and dark palettes. This way, when you call <code>MaterialTheme.colors.&lt;Color&gt;</code>, the system will handle the conditional logic necessary to pick the appropriate palette:</p>
<pre><code class="lang-pgsql">@Composable
fun NewGameContent(
    onEventHandler: (NewGameEvent) -&gt; Unit,
    viewModel: NewGameViewModel
) {
    Surface(
        Modifier
            .wrapContentHeight()
            .fillMaxWidth()
    ) {
        ConstraintLayout(Modifier.background(MaterialTheme.colors.<span class="hljs-keyword">primary</span>)) { 
            //...
        }
        //...
      }
}
</code></pre>
<p>However, sometimes it is more suitable to write your own conditional logic...or I just got lazy. Fortunately Compose makes many such configurations available as properties:</p>
<pre><code class="lang-pgsql">@Composable
fun DoneIcon(onEventHandler: (NewGameEvent) -&gt; Unit) {
    Icon(
        imageVector = Icons.Filled.Done,
        tint = <span class="hljs-keyword">if</span> (MaterialTheme.colors.isLight) textColorLight 
        <span class="hljs-keyword">else</span> textColorDark,
        contentDescription = <span class="hljs-keyword">null</span>,
        modifier = Modifier
            .clickable(
            //...
            )
    )
}
</code></pre>
<p><code>MaterialTheme.Colors.isLight</code> returns a boolean indicating what mode they are in, then we can use another Ternary Assignment from there.</p>
<h3 id="heading-how-to-style-a-text-composable">How to Style a Text Composable</h3>
<p>Just set the <code>style</code> argument equal to one of your text styles (whether it comes from <code>MaterialTheme</code> or one of the styles within <code>Type.kt</code>):</p>
<pre><code class="lang-kotlin">Text(
    text = stat.toTime(),
    style = statsLabel.copy(
        color = <span class="hljs-keyword">if</span> (isZero) Color.White
        <span class="hljs-keyword">else</span> MaterialTheme.colors.onPrimary,
    fontWeight = FontWeight.Normal
    ),
    modifier = Modifier
        .wrapContentSize()
        .padding(end = <span class="hljs-number">2</span>.dp, bottom = <span class="hljs-number">4</span>.dp),
        textAlign = TextAlign.End
)
</code></pre>
<p><code>TextStyle</code> has its own <code>copy</code> function ready to go should you need to overwrite anything.</p>
<p>And that's it! You now know how to style and theme an application using Jetpack Compose. Thanks for reading :)</p>
<h3 id="heading-social"><strong>Social</strong></h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<h3 id="heading-here-are-some-of-my-tutorials-amp-courses"><strong>Here are some of my tutorials &amp; courses</strong></h3>
<p><a target="_blank" href="https://www.youtube.com/channel/UCSwuCetC3YlO1Y7bqVW5GHg">https://youtube.com/wiseass</a> <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">https://www.freecodecamp.org/news/author/ryan-michael-kay/</a> <a target="_blank" href="https://skl.sh/35IdKsj">https://skl.sh/35IdKsj</a> (introduction to Android with Android Studio)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How is Visual and UX Design Important as a Developer and What Can You Do to Level Up? ]]>
                </title>
                <description>
                    <![CDATA[ Design is a part of the product process that often gets pushed off. This can come at a cost that your customers or other developers have to pay. How is design important for those of us who aren't just pushing pixels in Photoshop or Figma and what can... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-is-design-important-as-a-developer-and-what-can-you-do-to-level-up/</link>
                <guid isPermaLink="false">66b8e32b9232d58aac300b13</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design resources ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design thinking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lifelong Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ skills development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ visual design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 28 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/design.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Design is a part of the product process that often gets pushed off. This can come at a cost that your customers or other developers have to pay. How is design important for those of us who aren't just pushing pixels in Photoshop or Figma and what can we do to level up?</p>
<h2 id="heading-design-as-a-developer">Design as a developer</h2>
<p>Design is a term that can describe many parts of the process. Most often, it's probably thought of as the visual designers or UX designers who are actively working to make your product usable or beautiful.</p>
<p>A question that I commonly get asked or see online is where should one start to learn the basics of design?</p>
<p>This question makes me happy. It's an important part of the process that is constantly a secondary thought.  And when <a target="_blank" href="https://twitter.com/colbyfayock/status/1258456643274186753">I asked this on Twitter</a>, I received some thoughtful responses!</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1258456643274186753"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>We're living in an age where good UX is increasingly seen as important, but it's still nowhere near the top of the list for those who are learning their way through development. It's still an afterthought that's tossed over to the design team when you're at the 2nd half of your last sprint before launch.</p>
<p>So before I share with you some resources, I'm going to start by explaining why these things are important.</p>
<h2 id="heading-giving-something-for-your-visitors-to-use">Giving something for your visitors to use</h2>
<p>Starting from the top – you can have the best, most ingenious product that blows all competition away, but if no one knows how to use it, it realistically has no value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/02/pied-piper-user-interface.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fictional Pied Piper's app tanked because of a bad user experience</em></p>
<p>Our fictional friends at <a target="_blank" href="https://www.hbo.com/silicon-valley">Pied Piper</a> learned this the hard way when their product launch with a groundbreaking compression algorithm didn't go over too well because no one knew how to actually use it.</p>
<p>But this is a realistic scenario. We learned from <a target="_blank" href="https://craigslist.org/">Craigslist</a> that your website or app doesn't need to have a slick design, but it has to be usable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/craigslist-2020-vs-2001.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Craigslist in 2001 vs 2020</em></p>
<p>For nearly 20 years, Craigslist really hasn't changed that much. A few tweaks to make things a little bit cleaner, but overall it's the same basic layout and experience.</p>
<p>Unfortunately, budget is a concern, and sometimes you can only stretch it so much which doesn't always include a designer. But try to at least get some outside perspective – it can even be a family member or a friend! You would be surprised how much insight you can gather by trying to get your family over the holiday to try to use your app.</p>
<p>The goal is ultimately to get your product in front of someone that hasn't been heads down in it for the past year to get a pair of fresh eyes and a new perspective.</p>
<h2 id="heading-becoming-more-productive">Becoming more productive</h2>
<p>Putting on my process hat – another overlooked aspect of prioritizing design time is the amount of overall time you can possibly save.</p>
<p>Designers don't always get it right the first time, let alone leaving developers to create the design. That's not even including the possibility that your customer or product owner doesn't like the direction you took.</p>
<p>Why spend a couple sprints building out a solution only to start from scratch when you have to throw it all away? Not only have you wasted your customer's time, you've wasted your whole team's time.</p>
<p>Get design feedback early. Work with the design resources you have to iterate and work in feedback as you go. It's important to solve the UI problems before you develop the solutions.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/design-prototyping.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Design sketches from <a target="_blank" href="https://unsplash.com/photos/MKDEMlPRoYU">Unsplash.com</a></em></p>
<p>And this can generally help your team flesh out ideas. Visually seeing an idea, even as a rough sketch on a piece of paper or a disposable prototype, can completely change the way you look at the solution.</p>
<p>All of this early feedback and brainstorming will help you achieve the end-goal of a better product and user experience.</p>
<h2 id="heading-developers-are-users">Developers are users</h2>
<p>Most of people reading this post probably have written code in one form or another. But have you ever thought about how your code impacts other developers?</p>
<p>There are many layers to how your code can provide a better experience for another developer. The basic being – is the documentation that you created readable and easy to understand?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/strip-api-documentation.jpg" alt="Image" width="600" height="400" loading="lazy">
_<a target="_blank" href="https://stripe.com/docs/api/balance/balance_retrieve">Stripe's API documentation</a>_</p>
<p>While it's certainly important for your fellow teammates, they should typically be able to message you on Slack or hop on a call when they run into trouble. But how about those developers that only have your documentation?</p>
<p>Beautiful documentation isn't that which has a beautiful design, it's one that thoroughly walks through the code that you've created so that others can understand what it does and how they can use it. Just as a visitor to your app needs to know how to use the UI, a developer working with your services needs to know how to use the API.</p>
<h2 id="heading-a-little-extra-delight">A little extra delight</h2>
<p>But of course everyone wants something nice to look at. Not only can design treats make people happy and smile, it can also help avoid stress and tension.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/josh-w-comeau-website-heart-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Josh W. Comeau includes cute, happy graphics throughout his site</em></p>
<p>Having a page that's ugly or overly thick with data can be unsettling. Not only can it hurt the usability, but the clutter and color choices can make people feel uneasy, stressed, and full of anxiety.</p>
<p>While your team might not have the resources for full-time designers, taking a little time to learn the basics of design can help set you on your <a target="_blank" href="https://www.colbyfayock.com/2020/02/how-to-become-a-full-stack-web-developer-in-2020/">journey of becoming a well rounded developer</a>.</p>
<h2 id="heading-resources-for-learning-design-basics">Resources for learning design basics</h2>
<p>Like it or not – we're all "designers" in a way. We're all building tools and systems that ultimately will be used by another human being. We should do what we can to make our creations friendlier to use for everyone who comes next.</p>
<p>Since you're now inevitably inspired to spend some time and learn about design, there are luckily a lot of resources available for you to get started.</p>
<h3 id="heading-videos">Videos</h3>
<ul>
<li><a target="_blank" href="https://www.netflix.com/title/80057883">Abstract: The Art of Design</a> (Netflix)</li>
<li><a target="_blank" href="https://www.amazon.com/gp/video/detail/amzn1.dv.gti.fab0b754-6362-2da1-96a1-e3e538137141?tag=gmcs-fcc-20">Objectified</a> (Amazon)</li>
</ul>
<h3 id="heading-books">Books</h3>
<ul>
<li><a target="_blank" href="https://www.amazon.com/Design-Hackers-Reverse-Engineering-Beauty-ebook/dp/B005J578EW/?tag=gmcs-fcc-20">Design for Hackers</a> (Amazon)</li>
<li><a target="_blank" href="https://www.amazon.com/Non-Designers-Design-Book-Non-Designers-ebook/dp/B00PWDFWEE/?tag=gmcs-fcc-20">The Non-Designer's Design Book</a>  (Amazon)</li>
</ul>
<h3 id="heading-email-course">Email Course</h3>
<ul>
<li><a target="_blank" href="https://designforhackers.com/">Design for Hackers</a></li>
<li><a target="_blank" href="https://www.designacademy.io/free-course/">Design Academy</a></li>
<li><a target="_blank" href="https://hackdesign.org/">Hack Design</a></li>
</ul>
<h3 id="heading-misc">Misc</h3>
<ul>
<li><a target="_blank" href="https://twitter.com/i/events/994601867987619840">Design Tips from @steveschoger</a></li>
</ul>
<h2 id="heading-whats-your-take-on-design-as-a-developer">What's your take on design as a developer?</h2>
<p>Have any of these worked particularly well for you? Am I missing something that made design click for you? Please <a target="_blank" href="https://twitter.com/colbyfayock">share with me on Twitter</a>!</p>
<h2 id="heading-join-the-conversation">Join the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1265990400591966208"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
