<?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[ Material 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[ Material Design - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 04:44:38 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/material-design/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to make a custom theme in Angular Material ]]>
                </title>
                <description>
                    <![CDATA[ By Charlee Li Angular Material is a great library that implements Material Design for Angular 2+. The official document is sufficient regarding the component usages, while there are few articles about how to customize the theme itself, specifically, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-a-custom-theme-in-angular-material-d47122a1e361/</link>
                <guid isPermaLink="false">66c3533c1283974fd2bb079a</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Material Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 07 Dec 2018 00:37:26 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*u2PGM1dBW-M9oaRPMAVCXA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Charlee Li</p>
<p><a target="_blank" href="https://material.angular.io/">Angular Material</a> is a great library that implements <a target="_blank" href="https://material.io/design/">Material Design</a> for Angular 2+. The official document is sufficient regarding the component usages, while there are few articles about how to customize the theme itself, specifically, the colors used in the theme.</p>
<p>In this post I would like to summarize what I’ve learned these months from customizing Angular Material themes.</p>
<p><em>Note this article is NOT about <a target="_blank" href="https://material.angularjs.org/latest/">AngularJS Material</a>, which is used for <a target="_blank" href="https://angularjs.org/">AngularJS 1.x</a>.</em></p>
<h3 id="heading-related-posts">Related Posts</h3>
<p>Some common posts about customizing themes are:</p>
<ul>
<li>“<a target="_blank" href="https://material.angular.io/guide/theming">Theming your Angular Material app</a>”, the official guide for custom themes,</li>
<li>“<a target="_blank" href="https://medium.com/@tomastrajan/the-complete-guide-to-angular-material-themes-4d165a9d24d1">The complete guide to Angular Material Themes</a>” by <a target="_blank" href="https://medium.com/@tomastrajan?source=post_header_lockup">Tomas Trajan</a>, which provides many undocumented instructions. <strong>Strongly recommended</strong>.</li>
</ul>
<p>I didn’t find other useful posts and would appreciate if anyone could provide some resources in the comments.</p>
<h3 id="heading-how-to-create-a-custom-theme">How to Create a Custom Theme</h3>
<p>Creating a material theme is extremely simple: you only need to pick three colors — <strong>primary</strong>, <strong>accent</strong>, and <strong>warn</strong> — and Angular Material will do the rest for you. <a target="_blank" href="https://material.io/design/color/#tools-for-picking-colors">The material palette page</a> explains how it works clearly, and you can also create a theme visually with <a target="_blank" href="https://material.io/tools/color/">Color Tool</a>.</p>
<p>In regards to code, all you need to do is to create the following theme file:</p>
<pre><code><span class="hljs-comment">// theme.scss@import '~@angular/material/theming';</span>
</code></pre><pre><code>$my-theme-primary: mat-palette($mat-green);$my-theme-accent : mat-palette($mat-amber);$my-theme-warn   : mat-palette($mat-red);
</code></pre><pre><code>$my-theme: mat-light-theme(    $my-theme-primary,    $my-theme-accent,    $my-theme-warn);
</code></pre><p>Then you need to apply this theme in your main <code>style.scss</code> file:</p>
<pre><code>@<span class="hljs-keyword">import</span> <span class="hljs-string">"theme.scss"</span>;
</code></pre><pre><code>@include mat-core();@include angular-material-theme($my-theme);
</code></pre><h3 id="heading-how-to-use-custom-theme-in-components">How to Use Custom Theme in Components</h3>
<p>After creating our own theme, requirements like this will rise:</p>
<blockquote>
<p>I want to create a text box. The text color, background color, and border color should all come from our own theme, not by hard coding.</p>
</blockquote>
<p>This requirement is pretty common — anyway, being able to be used in components is exactly why we want to create a custom theme. The problem is how.</p>
<h4 id="heading-the-mixin-approach">The mixin approach</h4>
<p>The first official document I shared proposed a way of using SCSS’s mixin. I call it a “bottom-up” approach, which includes the following steps:</p>
<ol>
<li>Each component defines a theme mixin, and retrieves colors from <code>$theme</code> parameter.</li>
<li>A global <code>theme.scss</code> defines the custom theme, then includes all the component theme mixins and calls them with the custom theme.</li>
</ol>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZZFo93hwLrqUn3ntyKFegxNciXyufD0I3nnv" alt="Image" width="800" height="515" loading="lazy"></p>
<p>In addition to the <code>theme.scss</code> definition mentioned above, each component needs to create a theme file like this:</p>
<pre><code><span class="hljs-comment">// src/app/comp-a/comp-a.theme.scss@import '~@angular/material/theming';</span>
</code></pre><pre><code>@mixin comp-a-theme($theme) {          <span class="hljs-comment">// define mixin  $primary: map-get($theme, primary);  // retrieve color def  button {                             // apply theme to component    background-color: mat-color($primary);  }}</span>
</code></pre><p>And probably you want a <code>custom-theme.scss</code> to import all the component level themes:</p>
<pre><code><span class="hljs-comment">// src/app/custom-theme.scss@import '~@angular/material/theming';@import 'src/app/comp-a/comp-a.theme';@import 'src/app/comp-b/comp-b.theme';</span>
</code></pre><pre><code>@mixin custom-themes($theme) {  @include comp-a-theme($theme);  @include comp-b-theme($theme);}
</code></pre><p>Then import the above <code>custom-theme.scss</code> in your <code>theme.scss</code>:</p>
<pre><code><span class="hljs-comment">// theme.scss...@import './custom-theme';@include custom-themes($my-theme);</span>
</code></pre><p>This hierarchy works, and probably is the only way <em>when you need to support multiple themes</em>.</p>
<p>However, most of the time we only support one theme, and using a mixin could be cumbersome. Mainly there are three disadvantages with this approach:</p>
<ol>
<li>Every single color reference needs a separate <code>.theme.scss</code> file.</li>
<li><code>custom-theme.scss</code> must know exactly which components provide custom themes. This creates unnecessary dependencies.</li>
<li>Most importantly, component level theme files are not encapsulated.</li>
</ol>
<p>The first and second points are pretty self-explanatory. Let me explain a little bit about point 3. This involves some background knowledge called “View Encapsulation”.</p>
<p>Angular uses a technique called “<a target="_blank" href="https://angular.io/api/core/ViewEncapsulation">View Encapsulation</a>” to <a target="_blank" href="https://angular.io/guide/component-styles">keep component CSS local</a>. In other words, rules defined for one component will stay in that component and will not affect other components.</p>
<p>In this way you can define CSS class name freely in your component without worrying about naming conflicts. However, view encapsulation is done only if the CSS is defined through <code>@Component</code>, i.e. <code>@Component({ styleUrls: ['./comp-a.scss'] })</code>.</p>
<p>As to our custom theme file <code>comp-a.theme.scss</code>, since it is imported directly by <code>custom-theme.scss</code>, <em>its rules are not encapsulated</em> so it will apply to all elements on the page. In the example above, I used the following code (which was WRONG!):</p>
<pre><code>@mixin comp-a-theme($theme) {  button { ... }    <span class="hljs-comment">// This will apply to ALL buttons!}</span>
</code></pre><p>But this will apply the style to all the buttons instead of those buttons belonging to <code>comp-a</code> only. You have to do something like <code>comp-a button</code> in order to make this work correctly.</p>
<h4 id="heading-the-direct-approach">The direct approach</h4>
<p>Therefore I propose a better approach. Instead of using a mixin, we let each component include the theme file and use the color definition directly.</p>
<p>In this approach, the component theme file will look like this:</p>
<pre><code><span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> just do this in your regular scss file.// No need to create separate theme file!// src/app/comp-a/comp-a.scss@import 'src/theme.scss';</span>
</code></pre><pre><code>$primary: map-get($my-theme, primary);button {  background-color: mat-color($primary);}
</code></pre><p>And that’s all.</p>
<p>Let’s see how this works. First, theme related rules are put into the component SCSS file, so no extra component level theme file required. Second, the main <code>theme.scss</code> does not need to know component level themes (since it does not need to import them), so a simple theme definition is adequate. Third, the component SCSS file is used with <code>@Component</code> so it is encapsulated correctly, which means we can simply define rules for <code>button</code>.</p>
<h3 id="heading-predefined-theme-keys">Predefined Theme Keys</h3>
<p>Probably you have noticed the next problem. What are the <code>foreground</code>, <code>primary</code> in above theme files ( <code>map-get($my-theme, primary)</code>)? Are there any other keys I can use?</p>
<p>Well these “keys” refer to different colors defined in the theme. However I could not find any documents explaining these “keys”, so the only way I could find out is to <em>read the source code</em>. (Although it is said that good programmers should read the code, <em>having</em> to read the code is definitely not a good sign for a library.)</p>
<p>Open <code>node_modules/@angular/material/_theming.scss</code> and you will see the definitions for these keys. For future reference, I would like to summarize the keys here.</p>
<pre><code>$theme  |- primary  |- accent  |- warn  |- foreground  |   |- base  |   |- divider  |   |- dividers  |   |- disabled  |   |- disabled-button  |   |- disabled-text  |   |- hint-text  |   |- secondary-text  |   |- icon  |   |- icons  |   |- text  |   |- slider-min  |   |- slider-off  |   <span class="hljs-string">`- slider-off-active  |- background  |   |- status-bar  |   |- app-bar  |   |- background  |   |- hover  |   |- card  |   |- dialog  |   |- disabled-button  |   |- raised-button  |   |- focused-button  |   |- selected-button  |   |- selected-disabled-button  |   |- disabled-button-toggle  |   |- unselected-chip  |   `</span>- disabled-list-option  <span class="hljs-string">`- is-dark         // bool, whether dark theme or not</span>
</code></pre><p>For example, if you want to render a disabled text in your component, you may want to use the following code:</p>
<pre><code>$foreground: map-get($my-theme, foreground);.disabled-text {  <span class="hljs-attr">color</span>: mat-color($foreground, disabled-text);}
</code></pre><p>Okay these are some lessons I’ve learned from struggling with Angular Material. Hope this post is helpful if you are facing similar problems.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create a prototype in record time with the Material Theme Plugin for Sketch and Vuetify.js ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Wattis When developing an MVP (Minimum Viable Product), you intend to go from idea to prototype as fast as possible. The faster you can prototype your idea, the faster you are able to iterate upon it. As you’re moving from abstract idea to wo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/incredibly-fast-prototyping-with-material-theme-plugin-for-sketch-and-vuetify-js-366ef25ce9b3/</link>
                <guid isPermaLink="false">66c357fa71e87702d4e5b6d8</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Material Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ prototyping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vue.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 10 Jun 2018 23:58:55 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*-QMWv7Bv0N6QOcSUCeBu-Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Wattis</p>
<p>When developing an MVP (Minimum Viable Product), you intend to go from idea to prototype as fast as possible. The faster you can prototype your idea, the faster you are able to iterate upon it.</p>
<p>As you’re moving from abstract idea to working prototype, you usually don’t want to spend a lot of time creating a custom design when you should be focusing on the functionality of the application. To solve this issue, we use frameworks like Bootstrap to quickly achieve a structured layout with a UI that looks “pretty good” without too much effort.</p>
<p>What we really want to achieve, in terms of design, is to <strong>rapidly</strong> create a UI that is <strong>recognizable</strong> and <strong>coherent.</strong></p>
<p>I’m about to show you a super fast way of going from abstract idea, to design, to working prototype with Material Design. Material Design is Google’s open source design system that they use for all their applications. This makes it recognizable because it is intuitive and easy to navigate, and most people are familiar with it already. If you haven’t already, you should definitely check out what <a target="_blank" href="https://material.io/">Material design</a> is all about.</p>
<p>By using the Material Design Plugin for Sketch, we’ll create our own customizable Material Design system. This will include a great set of components that will allow us to quickly create coherent designs for our prototype app. The app we’ll make is a simple reminders app.</p>
<p>We will use front-end framework Vue.js together with the Material Design component library Vuetify.js to realize our app designs. Lets get to it!</p>
<h3 id="heading-creating-the-design-system">Creating the design system</h3>
<p><a target="_blank" href="https://material.io/tools/theme-editor/">Download</a> this plugin for Sketch. Once installed, simply go to Plugins &gt; Material &gt; Open Theme Editor to see the Material Design Theme Editor. Click “Create New Theme”, and we choose to begin with the Baseline theme.</p>
<p>We are now presented with our Material Design system of Sketch components.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/LuaHmcKZg8RwSJmcVazNctiDo75Sdf0KqHwP" alt="Image" width="800" height="452" loading="lazy">
<em>Your component library.</em></p>
<p>In the Theme Editor, you may change the primary and secondary color, change the font, change the shape of elements’ corners, and include custom icons. For this example, we will change none of these and just stick with the defaults.</p>
<p>We have now created our design system. As you can see, it says that the document is a <strong>library</strong>. This means that any changes you make to this Sketch file will affect your mock-ups and update all your designs with those changes. How great is that?</p>
<p>Before we continue, we will also install the Sketch Material plugin, which will add some modules that we’ll soon use.</p>
<h3 id="heading-mock-ups"><strong>Mock-ups</strong></h3>
<p>Let’s start by opening a new Sketch document then creating a new iPhone artboard and saving it as <strong>MaterialReminders.sketch</strong>. This is where we’ll create our designs for our application. But first, lets explore the rich component library that is at our disposal.</p>
<p>Under <strong>Insert &gt; Symb</strong>ols you should see the component library we just created.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vxaJm-KKTX25ZzXOZV1KeHcchXY63uvpyN12" alt="Image" width="800" height="596" loading="lazy">
<em>Explore all the components in our library and imagine the possibilities!</em></p>
<p>Just so many components! We can now begin to create our designs. But first we must break down what functionality we want this reminders app to have. We’re keeping it simple and only adding the ability to:</p>
<ul>
<li>Add a new reminder</li>
<li>Delete a reminder</li>
<li>Check off a reminder from your todo list</li>
<li>Uncheck a reminder from your completed list</li>
</ul>
<p>Fantastic, let’s speed things up and begin dropping some components into our first iPhone artboard.</p>
<p>We start with a top navbar. Drop it in and place it then size it to fit the screen. We’ll have to change the first icon to an “Icon / Add / Filled” for the Menu Icon and change icon color to white. Then change all the other icons to none, since we wont be needing them. We also change the headline to Reminders.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZCb-U7Is9ahlpicmLCUmc93MeN4CpWUj-FhF" alt="Image" width="640" height="359" loading="lazy">
<em>Customizing for your needs becomes super easy with symbol overrides.</em></p>
<p>We’ll now start dropping in some dummy reminders. We’ll create our reminders like a list, so let’s find a suitable component. We’ll use “List / Single Line / Indent / Body 2”.</p>
<p>Now we will center the list object, take away the bottom divider, set the text to “Chores”, and lastly change the icon to “Icon / Checked Circle / Outlined”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9Prfl9hSretZJqgP0l-AhgJ0ey7uVXKSZVmR" alt="Image" width="640" height="350" loading="lazy"></p>
<p>Add a title by inserting a text field, then using the Plugins &gt; Sketch Material &gt; Typography module to change the style to Subhead.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/tINK-Ts33QE0vIUe4orSqhCF8oNVsP4t3-p2" alt="Image" width="800" height="344" loading="lazy">
<em>When selecting a text field and going to the Typography module you can click on a style to apply it.</em></p>
<p>It’s beginning to look pretty good so far! But we are now faced with a problem. We want to also include list controls to the <em>right</em> in each list object, because we want to add a delete button there. But the devs over at Google did not include any override for that in the Sketch component. No worries though, we’ll fix this by going into our library file and adding our icon to the symbol, thus updating it throughout our project.</p>
<p>Go to the library and find the list component we used in the Material Components page. Then, double click it to go to its symbol. Click the icon to the left so that it is in focus, then copy paste and move it over to the right. Done deal.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/S8X8VqUhxaBO0GjO92TkQz0-sxDn3UjSCKh1" alt="Image" width="640" height="614" loading="lazy"></p>
<p>When we switch back over to our project, we can now see that in the the top right corner it says “Library Updates Available”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0FUd44ijqurPseWYOj3eSPZiHhjhDgO1ckiU" alt="Image" width="518" height="238" loading="lazy">
<em>Changes have been detected in the library. You may choose to update your designs with these new changes.</em></p>
<p>Now we should be able to change the right hand icon to “Icon / Close / Filled” which will be the button to remove a reminder completely from the list.</p>
<p>To create a list of reminders, we simply copy paste a bunch more list objects, change their text, then change the title that we added to Todo.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-TrerR8NqmxuW9wOCg9wz2aDGTyPiUzzzdOA" alt="Image" width="800" height="530" loading="lazy">
<em>Todo list is complete.</em></p>
<p>Then we copy paste that entire list to create the Completed list. On this new list, you must change the title to “Completed”, then change all the icons to the left to be filled instead of outlined.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AcZpO-zEL-N5FIEcPk5yDThcsL83K50ozWQt" alt="Image" width="640" height="388" loading="lazy">
<em>Select all the list items to change the icons to them all at the same time.</em></p>
<p>Were almost done with our mock-ups. To speed things along, I just changed our artboard color to #FAFAFA and added a “Shadow / 00dp” behind each of my lists.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/JoFxDKR5zSuNcGsBZgh9em9RRu15tH2hkYoQ" alt="Image" width="766" height="1132" loading="lazy">
<em>Completed mock-up.</em></p>
<p>This mock-up view is now complete. The next one we need to create is the dialogue that appears when you press the add button.</p>
<p>We begin by copy pasting the artboard we’ve been working on to create an exact copy. Then, we use the Dialogue and Form modules under “Plugins / Sketch Material” to create a dialogue and a form separately. These are then combined and a opaque box is placed behind. I switched out the transparent action button in the dialogue to a primary colored button.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aelleiqG6FnghDdfwGT9YtRF7jnYn8OfMvrp" alt="Image" width="786" height="1112" loading="lazy"></p>
<p>We are now done with Sketch. Of course, we could add more features and expand our mock-ups even more, but we will keep it simple for now. The next step is to write the code that will become our app!</p>
<h3 id="heading-vue-with-vuetify">Vue with Vuetify</h3>
<p>Now to the fun part — coding. We will be using Vue.js which is a front-end UI library written in JavaScript. It’s really easy to learn, and checking out their <a target="_blank" href="https://vuejs.org/v2/guide/">website</a> would be a first step. To implement Material Design, we’ll use the <a target="_blank" href="https://vuetifyjs.com/en/getting-started/quick-start">Vuetify.js</a> component library which includes a bunch of Vue components along with a grid system to easily organize your layout.</p>
<p>We start by simply copy pasting the example markup that’s on the Vuetify starter page. Let’s look at what this does for us.</p>
<p>When looking at HTML, start from the outside and work you way inwards.</p>
<p>We have our <code>&lt;head&gt;</code> and &amp;<code>lt;body&gt;&lt;/bo</code>dy&gt; tags.<code>Inside the &amp;l</code>t;head<code>&gt;&lt;/head&gt; tag we have &lt;lin</code>k&gt; tags that` will pull in the required vuetify.min.css file and Google Fonts.</p>
<p>In the <code>&lt;body&gt;&amp;</code>lt;/body&gt;<code>; we have a</code> </p><div></div> and within that we have some Vuetify <code>components, for</code> exam<code>ple &lt;v-app&gt;&lt;/v</code>-app&gt; and , which are signified by the “v-” in their names.<p></p>
<p>Further down you have two <code>&lt;script&gt;&lt;</code>;/script&gt; tags that import the Vue.js and Vuetify.js modules into our page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/q0VKlrkzc1mWE6qa2hyVy2sBYK0gLKlTtDin" alt="Image" width="800" height="327" loading="lazy"></p>
<p>Lastly, after the import statements, there is a third <code>&lt;script&gt;&lt;</code>;/script&gt; tag which cr<code>eates</code> a new Vue() instance. This is where we will write all our JavaScript code.</p>
<p>We can see that the instance is hooking into <code>‘#app’</code> which is the ID of the <code>&lt;div&gt;</code> tag in our HTML. This lets our Vue instance know where to inject our UI.</p>
<p>Inside of the <code>&lt;v-content&gt;&lt;/v</code>-content&gt; tag we will soon place all our Vuetify components. But first we will save what we have for now as index.html, and then open the file in our browser, where we should be presented with “Hello world”.</p>
<p>We continue by looking up what HTML we need for the top navbar component in the Vuetify documentation. The tag we’re looking for is <code>&lt;v-toolbar app&gt;&lt;/v</code>-toolbar&gt; . We’ll also ha<code>ve to add a &lt;</code>;v-btn&gt; inside this navbar so that we can press it to display the dialogue to add new reminders.</p>
<p>In this button we’ll also add a <code>@click=</code> event which will set <code>addModal</code> to <code>true</code> which will bring up the dialogue modal. We add this in between the <code>&lt;v-content&gt;&lt;/v</code>-content&gt; tags:</p>
<pre><code>&lt;v-toolbar app color=<span class="hljs-string">"primary"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"primary darken-1"</span> <span class="hljs-attr">icon</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"addModal = true"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>add<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span></span>  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">v-toolbar-title</span>&gt;</span>    Reminders  <span class="hljs-tag">&lt;/<span class="hljs-name">v-toolbar-title</span>&gt;</span></span>&lt;/v-toolbar&gt;
</code></pre><p>Next, we must add the HTML for the dialogue. This will live right after the <code>&lt;v-toolbar-title&gt;&lt;/v-toolb</code>ar-title&gt; tag, but still <code>inside the &lt;v-toolb</code>ar&gt; tag. Here is the dialogue:</p>
<pre><code>&lt;v-dialog v-model=<span class="hljs-string">'addModal'</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">v-card</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">v-card-title</span>&gt;</span>Add a reminder<span class="hljs-tag">&lt;/<span class="hljs-name">v-card-title</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">v-card-text</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">v-container</span> <span class="hljs-attr">grid-list-md</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">v-layout</span> <span class="hljs-attr">wrap</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-flex</span> <span class="hljs-attr">md12</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-text-field</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"newTask"</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"New task"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-text-field</span>&gt;</span>          <span class="hljs-tag">&lt;/<span class="hljs-name">v-flex</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-flex</span> <span class="hljs-attr">md12</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"primary"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"add"</span>&gt;</span>Add<span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>          <span class="hljs-tag">&lt;/<span class="hljs-name">v-flex</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">v-layout</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">v-container</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-text</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">v-card</span>&gt;</span></span>&lt;/v-dialog&gt;
</code></pre><p>Here we add a <code>&lt;v-card-tit</code>le&gt; with “Add a reminder” as a title. Then we use the Vuetify grid system to create a list that spans all 12 columns. We <code>add a &lt;v-te</code>xt-field&gt; th<code>at binds</code> to 'newTask' and has a lable that says “New task”. There will also be a button that, <code>through</code> the @click= event, t<code>rigge</code>rs the 'add' function that we’ll write in just a second.</p>
<p>After saving the changes to your document, you should end up with something like this when you refresh your index.html page in your browser:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Sehm8NfdIO65eutcubldfukWd9A1kYIaAhob" alt="Image" width="674" height="480" loading="lazy"></p>
<p>Don’t worry that the dialogue does not yet work — we must first add the functionality for it inside our <code>Vue()</code> instance. We do this by adding the following to our instance right after the <code>el: '#app'</code> but separated by a comma:</p>
<pre><code>el: <span class="hljs-string">'#app'</span>,<span class="hljs-attr">data</span>: {  <span class="hljs-attr">addModal</span>: <span class="hljs-literal">false</span>,  <span class="hljs-attr">newTask</span>: <span class="hljs-string">''</span>}
</code></pre><p>The <strong>data</strong> object is where we will store our application state. With this tweak, our dialogue should now work. Save and refresh the page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2fjdoJY-cmsKeXhu4y4-lEpYUzbocHiWwDYB" alt="Image" width="670" height="1020" loading="lazy"></p>
<p>Now whenever you click to open your dialogue modal, the internal state in <code>data: {}</code> is set to <code>addModal: true</code>, which then displays the modal. Similarly, whenever you write a message in the dialogue’s text input, it will be saved in <code>newTask</code> since the <code>&lt;v-text-field&gt;&lt;/v-te</code>xt-field&gt; is bound to <code>it thro</code>ugh v-model=.</p>
<p>We’ll now add the code for the <code>add</code> function that will save whatever is inside <code>newTask</code> to our soon-to-be list of reminders. This function must be located inside the <strong>methods</strong> object, which we’ll add after our <code>data: {},</code> object in the Vue instance.</p>
<p>The function will look like this:</p>
<pre><code>add() {  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.newTask !== <span class="hljs-string">''</span>) {    <span class="hljs-built_in">this</span>.tasks.unshift({<span class="hljs-attr">text</span>: <span class="hljs-built_in">this</span>.newTask, <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>})    <span class="hljs-built_in">this</span>.addModal = <span class="hljs-literal">false</span>    <span class="hljs-built_in">this</span>.newTask = <span class="hljs-string">''</span>  }}
</code></pre><p>After enclosing the function inside the <code>method: {}</code> object, the code should now look like this:</p>
<pre><code><span class="hljs-keyword">new</span> Vue({  <span class="hljs-attr">el</span>: <span class="hljs-string">'#app'</span>,  <span class="hljs-attr">data</span>: {    <span class="hljs-attr">addModal</span>: <span class="hljs-literal">false</span>,    <span class="hljs-attr">newTask</span>: <span class="hljs-string">''</span>,    },  <span class="hljs-attr">methods</span>: {    add() {      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.newTask !== <span class="hljs-string">''</span>) {        <span class="hljs-built_in">this</span>.tasks.unshift({<span class="hljs-attr">text</span>: <span class="hljs-built_in">this</span>.newTask, <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>})        <span class="hljs-built_in">this</span>.addModal = <span class="hljs-literal">false</span>        <span class="hljs-built_in">this</span>.newTask = <span class="hljs-string">''</span>      }    }  }});
</code></pre><p>When the <code>add()</code> function fires, it will add our task from <code>newTask</code> to our not-yet created tasks list unless it’s empty. It will then close the dialogue by setting <code>this.addModal = false</code> and set the <code>newTask</code> to empty again.</p>
<p>Let’s create our task list so that we can begin entering some reminders. Inside the <code>data</code> object, place this code:</p>
<pre><code>tasks: [   <span class="hljs-comment">// Some dummy data   {    text: 'Chores',    completed: false   },   {    text: 'More chores',    completed: false   }]</span>
</code></pre><p>These will be our dummy reminders. As you can see, we have a <code>completed</code> key that is set to either <code>true</code> or <code>false</code> so that we can differentiate between the tasks that are completed and those which are not. This also means that we can’t simply display our <code>tasks</code> list as it is in our UI, because then we would be displaying completed and non-completed tasks together.</p>
<p>The way we’ll solve this is with <strong>computed properties.</strong> They work by constantly watching for changes in your application and returning a computed value based on the changes.</p>
<p>We need two computed properties: one for the <code>todo</code> list and one for the <code>done</code> list that will each separate incomplete and completed tasks. We add <code>computed: {}</code> after our <code>methods: {},</code> and drop in <code>todo: function() {}</code> and <code>done: function() {}</code> computed properties. The <code>todo</code> function will <code>return this.tasks.filter(function(task) {return !task.completed})</code> and the <code>done</code> function will return the opposite by removing the <code>!</code> (which means “not”) in front of <code>task.completed</code> . The code should look like this:</p>
<pre><code>computed: {  <span class="hljs-attr">done</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{   <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasks.filter(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">task</span>) </span>{<span class="hljs-keyword">return</span> task.completed})  },  <span class="hljs-attr">todo</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{   <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasks.filter(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">task</span>) </span>{<span class="hljs-keyword">return</span> !task.completed})  }}
</code></pre><p>We’re now ready to render our two lists in our UI. This is going to be quite a bit of markup, but don’t worry, we’ll walk through it together. We’re going to replace <code>&lt;v-container&gt;Hello world&lt;/v-c</code>ontainer&gt; by selecting it and then pasting in the following in its place:</p>
<pre><code>&lt;v-container grid-list-md&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">v-layout</span> <span class="hljs-attr">row</span> <span class="hljs-attr">wrap</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">v-flex</span> <span class="hljs-attr">xs12</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">v-list</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">v-subheader</span>&gt;</span>Tasks to do<span class="hljs-tag">&lt;/<span class="hljs-name">v-subheader</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"task in todo"</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-action</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span> <span class="hljs-attr">ripple</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"complete(task)"</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"task.completed"</span>&gt;</span>check_circle<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">v-else</span>&gt;</span>check_circle_outline<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-action</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-title</span>&gt;</span>            {{task.text}}          <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-title</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-action</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span> <span class="hljs-attr">ripple</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"remove(task)"</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"grey lighten-1"</span>&gt;</span>cancel<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>          <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-action</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">v-list</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">v-flex</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-flex</span> <span class="hljs-attr">xs12</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">;v-list</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">v-subheader</span>&gt;</span>Completed tasks<span class="hljs-tag">&lt;/<span class="hljs-name">v-subheader</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"task in done"</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-action</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span> <span class="hljs-attr">ripple</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"complete(task)"</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"task.completed"</span>&gt;</span>check_circle<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">v-else</span>&gt;</span>check_circle_outline<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-action</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-title</span>&gt;</span>            {{task.text}}          <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-title</span>&gt;</span>          <span class="hljs-tag">&lt;<span class="hljs-name">v-list-tile-action</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span> <span class="hljs-attr">ripple</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"remove(task)"</span>&gt;</span>              <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"grey lighten-1"</span>&gt;</span>cancel<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>          <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile-action</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">v-list-tile</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">v-list</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">v-flex</span>&gt;</span></span>  &lt;<span class="hljs-regexp">/v-layout&gt;&lt;/</span>v-container&gt;
</code></pre><p>To begin with, we add <code>grid-list-md</code> to our container. Then we add <code>&lt;v-layout row wrap&gt;&lt;/</code>v-lay<code>out&gt; and &lt;v-fl</code>ex xs12&gt; and add o<code>ur two &lt;v-</code>list&gt; tag`s with a  in each. This creates our basic layout in form of two lists.</p>
<p>Then, we will add <code>&lt;v-list-tile v-for="task in todo"&gt;&lt;/v-l</code>ist-tile&gt;<code>; wher</code>e the v-for= statement iterates t<code>hrou</code>gh each task in o<code>ur c</code>omputed todo property. Same thing g<code>oes</code> for the done property. As we iterate through each list we will render each list item. Each item will <code>display t</code>he task.text and will have two buttons: one for tri<code>ggering th</code>e complete() function and one to <code>trigger</code> the remove() function.</p>
<p>Let’s continue by writing these inside of our <code>method</code> object.</p>
<pre><code>complete(task) {  task.completed ? task.completed = <span class="hljs-literal">false</span> : task.completed = <span class="hljs-literal">true</span>},remove(task) {  <span class="hljs-built_in">this</span>.tasks = <span class="hljs-built_in">this</span>.tasks.filter(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>)</span>{<span class="hljs-keyword">return</span> x !== task})},
</code></pre><p>The <code>complete</code> function body contains a ternary operator which will toggle the complete button on each reminder. Whenever <code>task.completed</code> is set to <code>true</code> on a reminder, the entire UI will update and move this reminder to the “Completed” list.</p>
<p>You should now have a real working prototype of our reminder application!</p>
<h3 id="heading-final-thoughts">Final thoughts</h3>
<p>In this article, I was not trying to show how to specifically build a useless reminders app with limited functionality (although that is exactly what I did). Rather, that you can use these tools that I have presented to you to very rapidly build a collection of mock-ups and then, with minimal setup, create a real, working prototype from these designs.</p>
<p>With this in place you can now tweak your component library, build out your designs, and then quickly implement them in code as you go along.</p>
<p>You can find the finished Sketch file and code <a target="_blank" href="https://github.com/adamwattis/MaterialReminders">here</a>. I also strongly recommend diving deeper into the tools I’ve talked about to fully realize their potential.</p>
<p>Hope you enjoyed this article and that you find it useful. Comment if you have any questions or let me know what you thought of it.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to show in-app messages using Material-UI in a React web app ]]>
                </title>
                <description>
                    <![CDATA[ By Kelly Burke In some situations, your web app needs to show an informational message to tell users whether an event was successful or not. For example, a “Success” message after a user clicks a button and successfully completes some action. In this... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-show-informational-messages-using-material-ui-in-a-react-web-app-5b108178608/</link>
                <guid isPermaLink="false">66c354baf9ee3cf1095598cb</guid>
                
                    <category>
                        <![CDATA[ Material Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 27 Apr 2018 23:33:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*awO-09f5MGtVvnkbVLoBDA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kelly Burke</p>
<p>In some situations, your web app needs to show an informational message to tell users whether an event was successful or not. For example, a “Success” message after a user clicks a button and successfully completes some action.</p>
<p>In this tutorial, I’ll show you how to create a simple component for informational, in-app messages with React and Material-UI. We’ll call it a <code>Notifier</code> component.</p>
<p>Here are the main sections of this tutorial:</p>
<ul>
<li>Getting started</li>
<li>Notifier component</li>
<li>Import Notifier component to Index page</li>
<li>Testing</li>
</ul>
<p>If you find this article useful, consider starring our <a target="_blank" href="https://github.com/builderbook/builderbook">Github repo</a> and checking out our <a target="_blank" href="https://builderbook.org/book">book</a> where we cover this and many other topics in detail.</p>
<h3 id="heading-getting-started"><strong>Getting started</strong></h3>
<p>For this tutorial, I’ve created a simple web app for you to follow. We’ll use code located in the <a target="_blank" href="https://github.com/builderbook/builderbook/tree/master/tutorials/4-start">tutorials/4-start</a> folder of our <a target="_blank" href="https://github.com/builderbook/builderbook">builderbook repo</a>.</p>
<p>If you don’t have time to run the app locally, I deployed this example app <a target="_blank" href="https://notifier.builderbook.org">here</a>.</p>
<p>To run the app locally:</p>
<ul>
<li>Clone the builderbook repo to your local machine with:</li>
</ul>
<pre><code>git clone git@github.com:builderbook/builderbook.git
</code></pre><ul>
<li>Inside the <code>4-start</code> folder, run <code>yarn</code> or <code>npm install</code> to install all packages listed in <code>package.json</code>.</li>
<li>Run <code>yarn dev</code> to start the app.</li>
</ul>
<h4 id="heading-index-page">Index page</h4>
<p>On your browser, go to <a target="_blank" href="http://localhost:3000">http://localhost:3000</a>. This is our <code>Index</code> page, which has the <code>/</code> route. Next.js provides automatic routing for pages located in a <code>/pages</code> folder. The name of each page file becomes that page’s route.</p>
<p>Our <code>Index</code> page is a simple page component that renders a form, an input, and a button (more explanation below).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*I50gTzdSn6aPSI3JYk9Hqw.png" alt="Image" width="800" height="166" loading="lazy"></p>
<p>Here’s the code for our <code>Index</code> page at <code>pages/index.js</code>:</p>
<p>A few notes:</p>
<ul>
<li>We could have defined this page as a stateless functional component, since it has no state, lifecycle hooks, or refs (<a target="_blank" href="https://www.jstwister.com/post/react-stateless-functional-components-best-practices/">read more</a> about when to use stateless functional components versus React ES6 classes). You’ll see this Eslint warning: <code>Component should be written as a pure function</code>. However, the <strong>final</strong> <code>Index</code> page that we write in this tutorial will have ref. Hence, we wrote this <strong>initial</strong> <code>Index</code> page as a child of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">ES6 class</a> using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a>.</li>
<li>We imported <a target="_blank" href="https://github.com/zeit/next.js/#populating-head">Head</a> from Next.js in order to customize the <code>&lt;He</code>ad&gt; element of the page. I<code>nside</code> , we a<code>dded a</code> page <code>&lt;t</code>itle&gt; and description for proper indexing by search engine bots (good fo<code>r SEO).</code> The text inside  displays on your browser tab:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*QtsMfsiewcSAb5AOE8LvsA.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We used Material-UI’s &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/api/text-field/#textfield"&gt;TextField&lt;/a&gt; and &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/demos/buttons/#buttons"&gt;Button&lt;/a&gt; components, which render into &lt;code&gt;&lt;inp&lt;/code&gt;ut&gt;&lt;code&gt;; and &amp;l&lt;/code&gt;t;button&gt; HTML elements, respectively.&lt;/li&gt;
&lt;li&gt;We wrapped our page with a &lt;code&gt;withLayout&lt;/code&gt; higher-order component. Our app uses Next.js, and &lt;code&gt;withLayout&lt;/code&gt; ensures that server-side rendering works properly for Material-UI inside our React-Next app. &lt;code&gt;withLayout&lt;/code&gt; also adds our &lt;code&gt;Header&lt;/code&gt; component (located at &lt;code&gt;components/Header.js&lt;/code&gt;) to each page that &lt;code&gt;withLayout&lt;/code&gt; wraps. Server-side rendering is not necessary for Material-UI or React, but it is a main feature of Next.js. We discussed &lt;a target='_blank' rel='noopener'  href="https://hackernoon.com/server-side-vs-client-side-rendering-in-react-apps-443efd6f2e87"&gt;server-side vs. client-side rendering&lt;/a&gt; in React apps in another tutorial.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are done describing our initial &lt;code&gt;Index&lt;/code&gt; page. Now let’s discuss the &lt;code&gt;Notifier&lt;/code&gt; component that we will later import into the &lt;code&gt;Index&lt;/code&gt; page to show informational messages to our web app users.&lt;/p&gt;
&lt;h3 id="heading-notifier-component"&gt;Notifier component&lt;/h3&gt;
&lt;p&gt;Let’s start by defining the &lt;code&gt;Notifier&lt;/code&gt; component. We define &lt;code&gt;Notifier&lt;/code&gt; as a &lt;code&gt;React.Component&lt;/code&gt; instead of a stateless function, because &lt;code&gt;Notifier&lt;/code&gt; will have state, one lifecycle method, and a few event handling functions.&lt;/p&gt;
&lt;p&gt;For our informational messages, we will use Material-UI’s &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/demos/snackbars/#snackbars"&gt;Snackbar&lt;/a&gt;. Check out &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/demos/snackbars/#snackbars"&gt;examples&lt;/a&gt; of using Snackbar on the official Material-UI site.&lt;/p&gt;
&lt;p&gt;Here’s a high-level outline of our &lt;code&gt;Notifier&lt;/code&gt; component:&lt;/p&gt;
&lt;p&gt;Create a &lt;code&gt;Notifier.js&lt;/code&gt; file inside the &lt;code&gt;/components&lt;/code&gt; folder of &lt;code&gt;4-start&lt;/code&gt;. Add the above high-level outline to this file. Below, we will replace the numbered comments with code.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We will use the &lt;code&gt;open&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt; props of Material-UI’s Snackbar for the state of our &lt;code&gt;Notifier&lt;/code&gt;. Check the &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/api/snackbar/#props"&gt;full list of props&lt;/a&gt; for Snackbar.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Initially, our &lt;code&gt;Notifier&lt;/code&gt; should be in a closed state with an empty string as a message. We define the &lt;code&gt;Notifier&lt;/code&gt;'s initial state as:&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Now let’s write a function that updates the state of the Notifier component. The function will change the value of the &lt;code&gt;open&lt;/code&gt; prop to &lt;code&gt;true&lt;/code&gt; and set the value of the &lt;code&gt;message&lt;/code&gt; prop to a non-empty string. Let’s call this function &lt;code&gt;openSnackbar()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Before we can execute &lt;code&gt;openSnackbar()&lt;/code&gt;, our &lt;code&gt;Notifier&lt;/code&gt; component needs to be mounted in the DOM. Thus, we put the &lt;code&gt;openSnackbar()&lt;/code&gt; function into a &lt;code&gt;componentDidMount&lt;/code&gt; lifecycle method that executes right after the &lt;code&gt;Notifier&lt;/code&gt; component mounts in the DOM.&lt;/p&gt;
&lt;p&gt;In order to access the &lt;code&gt;openSnackbar()&lt;/code&gt; function &lt;strong&gt;anywhere&lt;/strong&gt; in our app, we have to set its value to another function that is available outside of the &lt;code&gt;Notifier&lt;/code&gt; component. Hence, we write &lt;code&gt;let openSnackbarFn&lt;/code&gt; above &lt;code&gt;class Notifier extends React.Component&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Putting these pieces together:&lt;/p&gt;
&lt;p&gt;Now let’s define the &lt;code&gt;openSnackbar()&lt;/code&gt; function. This function will update the &lt;code&gt;open&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt; properties of our &lt;code&gt;Notifier&lt;/code&gt;’s state. Once the state is updated, the &lt;code&gt;Notifier&lt;/code&gt; component will get re-rendered to show a message (&lt;code&gt;open:true&lt;/code&gt; displays the Snackbar, and &lt;code&gt;message:message&lt;/code&gt; sets the message).&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;this.setState&lt;/code&gt;, we could have written &lt;code&gt;message&lt;/code&gt; as &lt;code&gt;message:message&lt;/code&gt;. Instead, we used ES6 &lt;a target='_blank' rel='noopener'  href="https://eslint.org/docs/rules/object-shorthand"&gt;shorthand syntax&lt;/a&gt; (enforced by Eslint) to make the code more concise.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;p&gt;When a user clicks outside of the Snackbar area, the Snackbar should close. The Snackbar prop &lt;code&gt;onClose&lt;/code&gt; is responsible for this behavior. Let’s write a function called &lt;code&gt;handleSnackbarClose()&lt;/code&gt; that sets &lt;code&gt;open&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt; to an empty string.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, let’s write code for our &lt;code&gt;Notifier&lt;/code&gt; component to render the Snackbar component with all necessary props.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition to the &lt;code&gt;message&lt;/code&gt;, &lt;code&gt;onClose&lt;/code&gt;, and &lt;code&gt;open&lt;/code&gt; props described above, we’ll add the following props to our Snackbar component:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;anchorOrigin&lt;/code&gt;: specifies the Snackbar location&lt;/li&gt;
&lt;li&gt;&lt;code&gt;autoHideDuration&lt;/code&gt;: specifies the Snackbar duration in milliseconds&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SnackbarContentProps&lt;/code&gt;: binds the Snackbar to an element inside the DOM that contains &lt;code&gt;message&lt;/code&gt;; in our case, the element has the id &lt;code&gt;snackbar-message-id&lt;/code&gt;, and the Snackbar will display text from this element.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the &lt;code&gt;render()&lt;/code&gt; method of our &lt;code&gt;Notifier&lt;/code&gt; component:&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;&lt;sp&lt;/code&gt;an&gt; element, we could have wr&lt;code&gt;itten message={this.state.me&lt;/code&gt;ssage}, but instead we &lt;code&gt;wrote dangerouslySetInnerHTML={{ __html: this.state.mess&lt;/code&gt;age }} . This allows us to add HTML code to the Snack&lt;code&gt;bar’s m&lt;/code&gt;essage prop. For instance, you may want to show a hyperlink to u&lt;a target='_blank' rel='noopener'  href="https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml"&gt;sers. Rea&lt;/a&gt;d more about using dangerouslySetInnerHTML in React.&lt;/p&gt;
&lt;p&gt;After putting the code from steps 1–4 together, here’s our final &lt;code&gt;Notifier&lt;/code&gt; component:&lt;/p&gt;
&lt;p&gt;Important note: notice how we exported our &lt;code&gt;openSnackbar()&lt;/code&gt; function in addition to &lt;code&gt;Notifier&lt;/code&gt; component. We will import &lt;strong&gt;both&lt;/strong&gt; &lt;code&gt;openSnackbar()&lt;/code&gt; and &lt;code&gt;Notifier&lt;/code&gt; into our &lt;code&gt;Index&lt;/code&gt; page.&lt;/p&gt;
&lt;h3 id="heading-import-notifier-component-to-index-page"&gt;Import Notifier component to Index page&lt;/h3&gt;
&lt;p&gt;Let’s go back to our &lt;code&gt;Index&lt;/code&gt; page, where we will import our &lt;code&gt;Notifier&lt;/code&gt; component and &lt;code&gt;openSnackbar()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;Without triggering the &lt;code&gt;openSnackbar()&lt;/code&gt; function, our &lt;code&gt;Notifier&lt;/code&gt; component will always stay in its initial closed state with an empty string as a message. We need to execute &lt;code&gt;openSnackbar()&lt;/code&gt; after a user submits the form by clicking the button on our &lt;code&gt;Index&lt;/code&gt; page. Let’s define a &lt;code&gt;showNotifier()&lt;/code&gt; function that does exactly that.&lt;/p&gt;
&lt;h4 id="heading-shownotifier-function"&gt;showNotifier Function&lt;/h4&gt;
&lt;p&gt;We will call &lt;code&gt;showNotifier()&lt;/code&gt; inside the &lt;code&gt;&lt;fo&lt;/code&gt;rm&gt; element. We’ll &lt;code&gt;make showNoti&lt;/code&gt;fier() execute when a user enters a number on the form and clicks the “Submit” button.&lt;/p&gt;
&lt;p&gt;Here’s the current &lt;code&gt;&lt;fo&lt;/code&gt;rm&gt; o&lt;code&gt;n our&lt;/code&gt; Index page:&lt;/p&gt;
&lt;p&gt;Let’s make two modifications:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To call &lt;code&gt;showNotifier()&lt;/code&gt; when the form is submitted, we use JavaScript’s &lt;a target='_blank' rel='noopener'  href="https://www.w3schools.com/jsref/event_onsubmit.asp"&gt;onsubmit Event&lt;/a&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A user will enter a number inside &lt;code&gt;TextField&lt;/code&gt;. In order for our &lt;code&gt;showNotifier()&lt;/code&gt; function to access the value of &lt;code&gt;TextField&lt;/code&gt;, we add React’s &lt;a target='_blank' rel='noopener'  href="https://reactjs.org/docs/refs-and-the-dom.html#adding-a-ref-to-a-dom-element"&gt;ref attribute&lt;/a&gt; to &lt;code&gt;TextField&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are two ways to get the value of &lt;code&gt;TextField&lt;/code&gt;: with &lt;code&gt;this.state&lt;/code&gt; and with &lt;code&gt;ref&lt;/code&gt;. We chose &lt;code&gt;ref&lt;/code&gt;, since &lt;code&gt;this.state&lt;/code&gt; is more concise. Here’s an &lt;a target='_blank' rel='noopener'  href="https://stackoverflow.com/questions/36683770/react-how-to-get-the-value-of-an-input-field?utm_medium=organic&amp;utm_source=google_rich_qa&amp;utm_campaign=google_rich_qa"&gt;explanation&lt;/a&gt; of writing with &lt;code&gt;this.state&lt;/code&gt;, and here’s &lt;a target='_blank' rel='noopener'  href="https://reactjs.org/docs/refs-and-the-dom.html#callback-refs"&gt;more info&lt;/a&gt; about using &lt;code&gt;ref&lt;/code&gt; in React.&lt;/p&gt;
&lt;p&gt;Now let’s define the &lt;code&gt;showNotifier()&lt;/code&gt; function. Here’s the high-level outline for &lt;code&gt;showNotifier()&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;Below, we’ll write code for each of the three comments above.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We define &lt;code&gt;answer&lt;/code&gt; as:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This line of code says that IF &lt;code&gt;answerInput&lt;/code&gt; exists (meaning the &lt;code&gt;&lt;inp&lt;/code&gt;ut&gt; element is added to the DOM), &lt;code&gt;THEN&lt;/code&gt; answer equals the val&lt;code&gt;ue of answe&lt;/code&gt;rInput, which is accessed &lt;code&gt;with answerInput&lt;/code&gt;.value.&lt;/p&gt;
&lt;p&gt;IF &lt;code&gt;answerInput&lt;/code&gt; does not exist, THEN the entire condition in parentheses is false and &lt;code&gt;answer&lt;/code&gt; equals &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;p&gt;If a user does not enter an answer on our form but clicks the “Submit” button, we will show this message: &lt;code&gt;Empty field. Enter a number.&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a user enters 4 and clicks the “Submit” button, then our &lt;code&gt;openSnackbar()&lt;/code&gt; function will run and show this message: &lt;code&gt;Correct answer!&lt;/code&gt;. Otherwise, it will show &lt;code&gt;Incorrect answer.&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We use &lt;code&gt;parseInt(answer, 10)&lt;/code&gt; to parse &lt;code&gt;answer&lt;/code&gt;, which is a string, and return an integer. The parameter &lt;code&gt;10&lt;/code&gt; specifies that the integer is in decimal format.&lt;/p&gt;
&lt;p&gt;Let’s put together the code from steps 1–3 above for our &lt;code&gt;showNotifier&lt;/code&gt; function. We’ll place the code right under the line &lt;code&gt;class Index extends React.Component&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;You’ll notice that we added a line &lt;code&gt;event.preventDefault();&lt;/code&gt;. This will prevent our &lt;code&gt;&lt;fo&lt;/code&gt;rm&gt; element from its default behavi&lt;a target='_blank' rel='noopener'  href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data"&gt;or of sending form data to a&lt;/a&gt; server.&lt;/p&gt;
&lt;p&gt;Now we have all the code for our final &lt;code&gt;Index&lt;/code&gt; page:&lt;/p&gt;
&lt;h3 id="heading-testing"&gt;Testing&lt;/h3&gt;
&lt;p&gt;Let’s test that our &lt;code&gt;Notifier&lt;/code&gt; works as expected. Run the app locally with &lt;code&gt;yarn dev&lt;/code&gt; and navigate to &lt;a target='_blank' rel='noopener'  href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;. If you aren’t running the app, go to the one I deployed: &lt;a target='_blank' rel='noopener'  href="https://notifier.builderbook.org"&gt;https://notifier.builderbook.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, click “Submit” without adding anything in the text field.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*tFZ2EbE513_ACJqNMPiHYw.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;Next, add the number 4 and click “Submit”.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*ov1Nt7TI_VcHWOgn-zb9WQ.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;Now add any other number and click “Submit”.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*61lDH0rzRRsReG4X36GV8A.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;Remember that we wrote code to close the Snackbar when a user clicks away from it (we wrote a &lt;code&gt;handleSnackbarClose()&lt;/code&gt; function and passed it to the &lt;code&gt;onClose&lt;/code&gt; prop of the Snackbar). After seeing the Snackbar, click anywhere besides the Snackbar itself on your screen. The Snackbar should close immediately.&lt;/p&gt;
&lt;p&gt;A nice feature of Material-UI is mobile optimization. We don’t have to write extra code for our informational message to look good on mobile devices. See for yourself by going to Chrome’s DevTools and changing the view from desktop to mobile. Our message appears across the top of the screen:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*3t4ur9VU3LOw2ytbKHrvAQ.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;Woohoo! You’ve successfully added an informational, in-app message to a React web app! Your final code should match the code in the &lt;a target='_blank' rel='noopener'  href="https://github.com/builderbook/builderbook/tree/master/tutorials/4-end"&gt;tutorials/4-end&lt;/a&gt; folder of our &lt;a target='_blank' rel='noopener'  href="https://github.com/builderbook/builderbook"&gt;builderbook repo&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id="heading-customize-notifier-component"&gt;Customize Notifier component&lt;/h4&gt;
&lt;p&gt;Now that you have a working &lt;code&gt;Notifier&lt;/code&gt; component, let’s see how we can modify the UX by changing props of Material-UI’s SnackBar component. Here’s the &lt;a target='_blank' rel='noopener'  href="https://material-ui-next.com/api/snackbar/#props"&gt;full list&lt;/a&gt; of props you can use.&lt;/p&gt;
&lt;p&gt;First, let’s change the duration of the Snackbar. Insider your &lt;code&gt;Notifier&lt;/code&gt; component, find the &lt;code&gt;autoHideDuration&lt;/code&gt; prop. Change its value from &lt;code&gt;3000&lt;/code&gt; to &lt;code&gt;1000&lt;/code&gt; and compare. You’ll see that at &lt;code&gt;1000&lt;/code&gt;, the Snackbar closes more quickly.&lt;/p&gt;
&lt;p&gt;Second, let’s change the position of the Snackbar. Find the &lt;code&gt;anchorOrigin&lt;/code&gt; prop and change its values from &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; to &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt;, respectively. Check where the Snackbar appears now:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*9ANw1zxyhHSQBOECUR_G2Q.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;Finally, let’s make the Snackbar &lt;code&gt;message&lt;/code&gt; include a hyperlink. Recall that we added &lt;code&gt;dangerouslySetInnerHTML={{ __html: this.state.message }}&lt;/code&gt; to our &lt;code&gt;message&lt;/code&gt; prop in the Snackbar so that we can write HTML inside of it.&lt;/p&gt;
&lt;p&gt;Change the code for our &lt;code&gt;Correct answer!&lt;/code&gt; and &lt;code&gt;Incorrect answer.&lt;/code&gt; messages like this:&lt;/p&gt;
&lt;p&gt;Now users will see the messages below. Notice the dark blue hyperlinks for text inside the &lt;code&gt;&lt;&lt;/code&gt;;a&gt; tags.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*fGzjKrwd2noPg34wQUOTCw.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn-media-1.freecodecamp.org/images/1*lYm3vmPuDAx4klVt33BwWw.png" alt="Image" class=""&gt;&lt;/p&gt;
&lt;p&gt;If you’re learning how to build web apps with JavaScript, check out our &lt;a target='_blank' rel='noopener'  href="https://github.com/builderbook/builderbook"&gt;Github repo&lt;/a&gt; and our &lt;a target='_blank' rel='noopener'  href="https://builderbook.org/book"&gt;book&lt;/a&gt;, where we cover this and many other topics in detail.&lt;/p&gt;
&lt;p&gt;To get email updates about our tutorials, subscribe &lt;a target='_blank' rel='noopener'  href="https://builderbook.org/tutorials"&gt;here&lt;/a&gt;.&lt;/p&gt;
</li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Material Design and the Mystery Meat Navigation Problem ]]>
                </title>
                <description>
                    <![CDATA[ By Teo Yu Siang In March 2016, Google updated Material Design to add bottom navigation bars to its UI library. This new bar is positioned at the bottom of an app, and contains 3 to 5 icons that allow users to navigate between top-level views in an ap... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/material-design-and-the-mystery-meat-navigation-problem-65425fb5b52e/</link>
                <guid isPermaLink="false">66c35b22f83dfae169b2c034</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Material Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 27 Jan 2017 04:20:09 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*zWh3_7qHGS1sWYzzEnhaXw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Teo Yu Siang</p>
<p>In March 2016, Google <a target="_blank" href="http://www.androidauthority.com/bottom-navigation-material-design-guidelines-680207/">updated</a> Material Design to add bottom navigation bars to its UI library. This new bar is positioned at the bottom of an app, and contains 3 to 5 icons that allow users to navigate between top-level views in an app.</p>
<p>Sound familiar? That’s because bottom navigation bars have been a part of <a target="_blank" href="https://developer.apple.com/ios/human-interface-guidelines/ui-bars/tab-bars/">iOS’s UI library</a> for years (they’re called tab bars in iOS).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7YItl6X12sekqS7gEvWob4GYqKgaeBZQHij9" alt="Image" width="800" height="56" loading="lazy">
<em>Left: Material Design’s bottom navigation bar | Right: iOS’s tab bar</em></p>
<p>Bottom navigation bars are <a target="_blank" href="http://www.lukew.com/ff/entry.asp?1945">a better alternative</a> to the hamburger menu, so their addition into Material Design should be good news. But Google’s version of bottom navigation bars has a serious problem: <strong>mystery meat navigation</strong>.</p>
<p>Whether you’re an Android user, designer, or developer, this should trouble you.</p>
<h3 id="heading-whats-mystery-meat-navigation-and-whys-it-so-bad">What’s mystery meat navigation, and why’s it so bad?</h3>
<p>Mystery meat navigation is a term coined in 1998 by Vincent Flanders of the famous website <a target="_blank" href="http://www.webpagesthatsuck.com/">Web Pages That Suck</a>. It refers to buttons or links that don’t explain to you what they do. Instead, you have to click on them to find out.</p>
<p>(The term “mystery meat” originates from the meat served in American public school cafeterias that were so processed that the type of animal they came from is no longer discernible.)</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/DCG0RcBAYpPo1PiWKyXvJ6udqLMKsAL4orlG" alt="Image" width="588" height="93" loading="lazy">
_An example of mystery meat navigation | [Source](http://gigi.nullneuron.net/gigilabs/on-mystery-meat-navigation-and-unusability/" rel="noopener" target="<em>blank" title=")</em></p>
<p><strong>Mystery meat navigation is the hallmark of designs that prioritize form over function.</strong> It’s bad UX design, because it emphasizes aesthetics at the cost of user experience. It adds cognitive load to navigational tasks, since users have to guess what the button does. And if your users need to guess, you’re doing it wrong.</p>
<p>You wouldn’t want to eat mystery meat—similarly, users wouldn’t want to click on mystery buttons.</p>
<h3 id="heading-strike-1-android-lollipops-navigation-bar">Strike 1: Android Lollipop’s Navigation Bar</h3>
<p>Material Design’s first major mystery meat navigation problem happened in 2014 with Android Lollipop.</p>
<p>Android Lollipop was introduced in the same conference that debuted Material Design, and sports a redesigned UI to match Google’s new design language.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Wdwchat-pQDuQX5nPu8I8w8ClC9iKK2wEA4T" alt="Image" width="720" height="92" loading="lazy">
<em>Navigation bar in earlier versions of Android</em></p>
<p>One of the UI elements that got redesigned was the navigation bar, the persistent bar at the bottom of Android OS that provides navigation control for phones without hardware buttons for Back, Home and Menu.</p>
<p>In Android Lollipop, the navigation bar was redesigned to this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7nRsekkx7N76oZ0R2901z7FLPs0JUBefoSJs" alt="Image" width="720" height="96" loading="lazy">
<em>Navigation bar, Android Lollipop and up</em></p>
<p>See the problem?</p>
<p>While the previous design is less aesthetically appealing, it’s more or less straightforward. The Back and Home icons can be understood without the need for text labels. The 3rd icon is a bit of a mystery meat, but on the whole, the UX of the old navigation bar wasn’t too bad.</p>
<p>The new bar, on the other hand, is <em>extremely</em> pretty. The equilateral triangle, circle, and square are symbols of geometric perfection. But it’s also <em>extremely</em> user-unfriendly. It’s abstract—and navigation controls should never be abstract. It’s full-blown mystery meat navigation.</p>
<p>The triangle icon might resemble a “Back” arrow, but what does a circle and a square mean in relation to navigation control?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/nvOaaRnehcqssATkE4qJY7MzIiba7GoPVrlE" alt="Image" width="800" height="573" loading="lazy">
<em>Making sense of the navigation bar icons</em></p>
<h3 id="heading-strike-2-floating-action-buttons">Strike 2: Floating Action Buttons</h3>
<p>Floating action buttons are special buttons that appear above other UI elements in an app. Ideally, they’re used to promote the primary action of the app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MwpSqGbO5h9GLia5FMdnpsMVsxz0-SbU5BbM" alt="Image" width="720" height="544" loading="lazy">
_Specs for the floating action button | [Source](https://material.io/guidelines/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button" rel="noopener" target="<em>blank" title=")</em></p>
<p>Floating action buttons also suffer from the mystery meat navigation problem. By design, the floating action button is a circle containing an icon. It’s a pure-icon button, with no room for text labels.</p>
<p>The truth is that <a target="_blank" href="http://uxmyths.com/post/715009009/myth-icons-enhance-usability"><strong>icons are incredibly hard to understand</strong></a> because they’re so open to interpretation. Our culture and past experiences inform how we interpret icons. Unfortunately, designers (especially, it seems, Material designers) have a hard time facing this truth.</p>
<p>Need proof that icon-only buttons are a bad idea? Let’s play a guessing game.</p>
<p>Below is a list of what—according to Material Design’s <a target="_blank" href="https://material.io/guidelines/components/buttons-floating-action-button.html">guidelines</a>—are acceptable icons for floating action buttons. Can you guess what each button does?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YvRDCuTrv7S8S76-ENqYBgS8GI8OjaIwXY-v" alt="Image" width="365" height="200" loading="lazy">
<em>Mystery button 1</em></p>
<p>Ok, that’s a simple one to warm you up. It represents “Directions”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2lqEudSZmyNmqGtpjrn4I2RtPYIZDbUnwwYL" alt="Image" width="365" height="200" loading="lazy">
<em>Mystery button 2</em></p>
<p>What about this? If you’re an iOS or Mac user, you might say “Safari.” It actually represents “Explore.”</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/UUHgLVPW5MWGIx-1tiy2JAghliERwnjw6gDe" alt="Image" width="365" height="200" loading="lazy">
<em>Mystery button 3</em></p>
<p>Things are getting fun (or frustrating) now! Could this be “Open in contacts”? “Help, there’s someone following me”? Perhaps this is a button for your “Phone a friend” lifeline.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QqiP6oceM0SVfMXfLxNPs4lajjSleb9kdb2g" alt="Image" width="365" height="200" loading="lazy">
<em>Mystery button 4</em></p>
<p>Hang on, <em>this</em> is the button for “Open in contacts.” Right? Or is this “Gossip about a friend” since the person is inside a speech bubble?</p>
<p>Ready for the final round? Here’s the worst (and most used) icon:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/eYdflx0Iu5vUqPOt2QKCO0LR52ndHAPD9pCt" alt="Image" width="365" height="200" loading="lazy">
<em>Mystery button 5</em></p>
<p>You might think the “+” button is rather simple to understand—it’s obviously a button for the “Add” action. But add <em>what</em>?</p>
<p><em>Add what:</em> that’s the problem right there. If a user needs to ask that question, your button is officially mystery meat. Sadly, developers and designers of Material Design apps seem to be in love with the “+” floating action button.</p>
<p>Precisely because the “+” button <em>seems</em> so easy to understand, it ends up being the most abused icon for floating action buttons. Consider how Google’s own Inbox app displays <em>additional</em> buttons when you tap the “+” floating button, which is not what a user would expect:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/f1EkSce5KKMIhKgbVxSkSisB5GnLbW6uly0y" alt="Image" width="506" height="900" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CIE3zt1sLgpfCwGBs0ivSgBkQ8PJYtQ1l9ox" alt="Image" width="506" height="900" loading="lazy">
<em>The “+” button opens up a menu of… more buttons?</em></p>
<p>What makes things worse is how the same icons have different meanings in different apps. Google used the pencil icon to represent “Compose” in Inbox and Gmail, but used it to represent “Edit” in its photo app Snapseed.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/31VNlRc307i36uGhWuNUC61Iib9ldA34nD7G" alt="Image" width="506" height="900" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/FdIG9drQMkrMFpYWlxHM4INmxjVtaM8tN53B" alt="Image" width="506" height="900" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ezUJoa3dZv6IUhS-QKYc6jWGiBc6apr12efj" alt="Image" width="750" height="1334" loading="lazy">
<em>Same icon, different meanings: “Compose” in the Gmail and Inbox apps, “Edit” in the Snapseed app</em></p>
<p>The floating action button was intended to be a great way for users to access a primary action. Except it isn’t, because icon-only buttons tend to be mystery meat.</p>
<p>More on floating action buttons:</p>
<p><a target="_blank" href="https://medium.com/tech-in-asia/material-design-why-the-floating-action-button-is-bad-ux-design-acd5b32c5ef"><strong>Material Design:</strong></a><br><a target="_blank" href="https://medium.com/tech-in-asia/material-design-why-the-floating-action-button-is-bad-ux-design-acd5b32c5ef"><strong>Why the Floating Action Button is bad UX design</strong></a><br><a target="_blank" href="https://medium.com/tech-in-asia/material-design-why-the-floating-action-button-is-bad-ux-design-acd5b32c5ef">_Material Design is a design language introduced by Google a year ago, and represents the company’s bold attempt at…_medium.com</a></p>
<h3 id="heading-strike-3-the-new-bottom-navigation-bar">Strike 3: The New Bottom Navigation Bar</h3>
<p>This brings us to the bottom navigation bar, introduced in March 2016.</p>
<p>For bottom navigation bars with 3 views, Google’s guidelines specify that both icons and text labels must be displayed. So far, so good: no mystery meat here.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YGvSiyZjDEce7u2NuFDrRyW7qS77YeOLOuEx" alt="Image" width="720" height="114" loading="lazy">
<em>Bottom navigation bar with 3 views: so far, so good</em></p>
<p>But for bottom navigation bars with 4 or 5 views, Google specifies that inactive views be displayed as <em>icons only</em>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/D7CeYD631OThLgasrNa4NyDb5HpB60IeJWhF" alt="Image" width="720" height="112" loading="lazy">
<em>Bottom navigation bar with 4 views: mystery meat</em></p>
<p>Remember how hard it was to guess what the floating action button icons mean? Now try guessing a row of icons used to navigate an app.</p>
<p>This is just bad UX design. In fact, the Nielsen Norman Group <a target="_blank" href="https://www.nngroup.com/articles/icon-usability/">argues</a> that icons <em>need</em> a text label, especially navigation icons (emphasis theirs):</p>
<blockquote>
<p>“To help overcome the ambiguity that almost all icons face, a <strong>text label must be present alongside an icon</strong> to clarify its meaning in that particular context.… For navigation icons, labels are particularly critical.”</p>
</blockquote>
<p>That Material Design’s newest UI component condones mystery meat navigation is not only frustrating, but also weird. Why should text labels be shown when there are 3 views, but be hidden when there are 4–5 views?</p>
<p>An obvious answer would be space constraints.</p>
<p>Except tab bars in iOS manage to contain 5 icons, and still display the icon and text label for each of them. So space constraint isn’t a valid reason.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XuHqU7P7rXUzZjAawfbA89u2Gj12Ll6DBQSh" alt="Image" width="750" height="1334" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8U5exm475tOlJbYAJW8PJeWECTC-PLX93G00" alt="Image" width="750" height="1334" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Cv6H3piHbcpMiAYyD7h0Ro1CsMi4tuhXw7ed" alt="Image" width="750" height="1334" loading="lazy">
<em>iOS tab bar in the App Store, Clock and Music apps: 5 icons, all with text labels</em></p>
<p>Google either decided that icons can sufficiently represent navigational actions (which is bad), or they decided that aesthetic neatness is more important than usability (which is worse). Either way, their decision worsened the UX of millions of Android users.</p>
<h3 id="heading-material-design-and-form-over-function">Material Design and Form over Function</h3>
<p>When Material Design was launched in 2014, it was to much fanfare. It’s bold, and rides on (and one-ups) the flat design trend. The pairing of vibrant colours and animations make it pretty to look at.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OLb76CbG4u49bqTlU4WNfUXsIWhcmHQ397no" alt="Image" width="800" height="450" loading="lazy">
_“Make it pretty!” — Material Design designer | [Source](https://www.youtube.com/watch?v=Q8TXgCzxEnw" rel="noopener" target="<em>blank" title=")</em></p>
<p>But perhaps it’s a little <em>too</em> pretty. Perhaps while working on Material Design, the designers got a little carried away.</p>
<p>Time and again, Google’s guidelines for important buttons and bars seem to prioritise form over function. Geometric prettiness was chosen over recognisability in Android’s navigation bar. Aesthetic simplicity was championed in floating action buttons, turning them into riddles in the process. Finally, visual neatness was deemed more important than meaningful labels in bottom navigation bars.</p>
<p>That’s not to say that mystery meat navigation is a Google-only problem. Sure, you can find mystery meat in iOS apps too. But they don’t usually appear in critical navigational controls and promoted buttons. They also aren’t spelt out specifically in design guidelines to be mystery meat.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/If7hVf7dEE1YQkJoUeavMmsb0BbrZ0ttLGyV" alt="Image" width="800" height="367" loading="lazy">
<em>Speed graph showing the correct (blue) acceleration for animations</em></p>
<p>If Google designers could devote time and effort into creating speed graphs for animations, perhaps they could spend a little time to make sure their designs aren’t mystery meat.</p>
<p>After all, an animated mystery button is still less delightful than a static but clearly labelled button.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Best Gitter channels: Material Design ]]>
                </title>
                <description>
                    <![CDATA[ By Gitter Material Design is a design language developed by Google. It consists of specifications for a unified system of visual, motion, and interaction design that adapts across different devices and different screen sizes. Material design is multi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-gitter-channels-material-design-2b137171083f/</link>
                <guid isPermaLink="false">66c345999972b7c5c7624e18</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Material Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 08 Mar 2016 13:08:49 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ATlLP0KYvl5shs9EJOOejg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gitter</p>
<p>Material Design is a design language developed by Google. It consists of specifications for a unified system of visual, motion, and interaction design that adapts across different devices and different screen sizes. Material design is multidimensional in its ability to communicate and react to user’s actions — it has been developed for the purpose of providing a consistent and unified user experience, both functional and aesthetically pleasing.</p>
<p>Check out the Material Design -related channels on <a target="_blank" href="https://gitter.im/">Gitter</a> &amp; join the conversation!</p>
<ul>
<li><a target="_blank" href="https://gitter.im/google/material-design-lite?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Google/material-design-lite</strong></a> <strong>—</strong> Material Design Lite (MDL) lets you add a Material Design look and feel to your static content websites. It doesn’t rely on any JavaScript frameworks or libraries. Optimized for cross-device use, gracefully degrades in older browsers, and offers an experience that is accessible from the get-go.</li>
<li><a target="_blank" href="https://gitter.im/Dogfalo/materialize?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Dogfalo/materialize</strong></a> <strong>—</strong> Materialize is a modern responsive front-end framework based on Material Design.</li>
<li><a target="_blank" href="https://gitter.im/callemall/material-ui?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Callemall/material-ui</strong></a> <strong>—</strong> Material-UI is a CSS framework and a set of <a target="_blank" href="http://facebook.github.io/react/">React</a> components that implement <a target="_blank" href="https://www.google.com/design/spec/material-design/introduction.html">Google’s Material Design</a> specification.</li>
<li><a target="_blank" href="https://gitter.im/angular/material?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Angular/material</strong></a> <strong>—</strong> For developers using AngularJS, Angular Material is the reference implementation of Google’s Material Design Specification. This project provides a set of reusable, well-tested, and accessible UI components based on Material Design.</li>
<li><a target="_blank" href="https://gitter.im/mikepenz/MaterialDrawer?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Mikepenz/MaterialDrawer</strong></a> <strong>—</strong> Material Drawer is a simple take on creating an easy to use and fast material navigation drawer implementation.</li>
<li><a target="_blank" href="https://gitter.im/papyros/qml-material?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Papyros</strong></a> <strong>—</strong> Papyros is a library of QML widgets implementing Google’s <a target="_blank" href="https://www.google.com/design/spec">Material Desig</a>n</li>
<li><a target="_blank" href="https://gitter.im/zachsoft/Ionic-Material?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Ionic-Material</strong></a> <strong>—</strong> Seamless Material Design theme for <a target="_blank" href="http://ionicmaterial.com">Ionic</a>.</li>
<li><a target="_blank" href="https://gitter.im/FezVrasta/bootstrap-material-design?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>FezVrasta</strong></a> <strong>—</strong> Material Design for Bootstrap is a Bootstrap V3 compatible theme — an easy way to use the new <a target="_blank" href="http://www.google.com/design/spec/material-design/introduction.html">Material Design guidelines by Google</a> in your Bootstrap 3 based application.</li>
<li><a target="_blank" href="https://gitter.im/viewflow/django-material?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Django-material</strong></a> <strong>—</strong> Material design for Django Forms and Admin. Template driven.</li>
<li><a target="_blank" href="https://gitter.im/liri-project/liri-browser?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=material"><strong>Liri-project/liri-browser</strong></a> — A minimalistic material design web browser written for <a target="_blank" href="https://github.com/papyros/">Papyros</a>.</li>
</ul>
<p>Are you looking for something else? Check out the <a target="_blank" href="https://gitter.im/explore/tags/javascript,php,ruby">Explore</a> section or easily <a target="_blank" href="https://gitter.im/home#createroom">start your own channel here</a>. Did we miss an channel that you think should be featured? Drop us a line in the <a target="_blank" href="https://gitter.im/gitterHQ/gitter">Gitter HQ</a> and we will add it to the list.</p>
<p>Happy designing!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
