<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jose Godinez  </title>
    <description>The latest articles on DEV Community by Jose Godinez   (@joseprest).</description>
    <link>https://dev.to/joseprest</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F671187%2F119943b6-dd0c-41e1-b6e7-d5ec00e41613.jpg</url>
      <title>DEV Community: Jose Godinez  </title>
      <link>https://dev.to/joseprest</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joseprest"/>
    <language>en</language>
    <item>
      <title>10 Tailwind CSS tips</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Sat, 01 Oct 2022 15:00:43 +0000</pubDate>
      <link>https://dev.to/joseprest/10-tailwind-css-tips-3jgk</link>
      <guid>https://dev.to/joseprest/10-tailwind-css-tips-3jgk</guid>
      <description>&lt;h2&gt;
  
  
  In your Tailwind config file, set !important to true.
&lt;/h2&gt;

&lt;p&gt;This option will append all the utility classes with the !important keyword.&lt;/p&gt;

&lt;p&gt;This is especially useful when you’re dealing with third-party libraries that add style to some elements. This way, you’ll make sure that when you add a new utility class to these elements, they will always be applied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
// tailwind.config.js
module.exports = {
  important: true,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, all of Tailwind’s utility classes will be generated as !important:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;css
.mt-1 {
  margin-top: 1px !important;
}
.mt-2 {
  margin-top: 2px !important;
}
.mt-3 {
  margin-top: 3px !important;
}
/* And so on... */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tired of centering and defining the padding of your main container class?
&lt;/h2&gt;

&lt;p&gt;Set some settings for your container in your configuration file and it will automatically be applied to all .container classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
// tailwind.config.js
module.exports = {
  theme: {
    container: {
      center: true,
      padding: "1.5rem",
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, there is no need to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
&amp;lt;div class="container p-6 mx-auto"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can just do this:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
&amp;lt;div class="container"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Don’t forget, you can still add your own utility classes
&lt;/h2&gt;

&lt;p&gt;The extend property in the configuration file will automatically generate and add new classes for your project. It is convenient when you need additional classes for a given CSS property.&lt;/p&gt;

&lt;p&gt;For instance, when it comes to max-height, you only have access to the following classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.max-h-full    /* max-height: 100%; */
.max-h-screen  /* max-height: 100vh; */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, what if you need to control the max-height property with a little bit more precision with classes like: max-h-xs, max-h-sm or max-h-md?&lt;/p&gt;

&lt;p&gt;Well, here’s how you can generate them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
    // tailwind.config.js
    module.exports = {
      theme: {
        extend: {
          maxHeight: {
            xs: "20rem",
            sm: "24rem",
            md: "28rem",
            lg: "32rem",
            xl: "36rem",
            "2xl": "42rem",
            "3xl": "48rem",
            "4xl": "56rem",
            "5xl": "64rem",
            "6xl": "72rem",
          },
        },
      },
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always know which breakpoint is currently active&lt;br&gt;
Tailwind CSS debug screen.&lt;br&gt;
The TailwindCSS Debug Screens plugin will let you display the currently active screen in development mode. It does not take more than a few seconds to set up, and it will probably save you a lot of time in the long run. This is how you can Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash
npm install tailwindcss-debug-screens --save-dev
javascript
// tailwind.config.js
module.exports = {
  plugins: [require("tailwindcss-debug-screens")],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the class debug-screens to your &lt;/p&gt; tag.&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
&amp;lt;body class="debug-screens"&amp;gt;&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  You can disable preflight if you need to integrate Tailwind in an existing project
&lt;/h2&gt;

&lt;p&gt;From the documentation: preflight is a set of base styles for Tailwind projects that are designed to smooth over cross-browser inconsistencies and make it easier for you to work within the constraints of your design system.&lt;/p&gt;

&lt;p&gt;This means that preflight will remove all of the default margins, font sizes, etc., for all your elements like your headings, blockquotes, lists, and so on.&lt;/p&gt;

&lt;p&gt;A few months ago, I needed to progressively integrate Tailwind into an existing project (which had rigorous base styles). The issue with preflight is that it was breaking all the application interfaces. It took me some time before I could find a way to disable it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
// tailwind.config.js
module.exports = {
  corePlugins: {
    preflight: false,
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you need to define your own breakpoints?&lt;br&gt;
If your designers are being used with breakpoints that are different from the ones provided by Tailwind, no worries! Just open your configuration file and define your own. Keep in mind that you can create breakpoints with both min-width and max-width definitions if necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      sm: { min: "640px", max: "767px" },
      md: { min: "768px", max: "1023px" },
      lg: { min: "1024px", max: "1279px" },
      xl: { min: "1280px" },
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;// Will equal to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      sm: "640px",
      // =&amp;gt; @media (min-width: 640px) { ... }
      md: "768px",
      // =&amp;gt; @media (min-width: 768px) { ... }
      lg: "1024px",
      // =&amp;gt; @media (min-width: 1024px) { ... }
      xl: "1280px",
      // =&amp;gt; @media (min-width: 1280px) { ... }
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Do you prefer px instead of the default rem for your padding, margins, width, and height?
&lt;/h2&gt;

&lt;p&gt;The spacing property in your configuration file allows you to override the default spacing/sizing scale in a snap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript
// tailwind.config.js
module.exports = {
  theme: {
    spacing: {
      "1": "8px",
      "2": "12px",
      "3": "16px",
      "4": "24px",
      "5": "32px",
      "6": "48px",
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to order flex-items
&lt;/h2&gt;

&lt;p&gt;You are probably used to the order property if you are using flexbox. Unfortunately, Tailwind does not include it.&lt;/p&gt;

&lt;p&gt;You will then be able to configure and generate the flexbox order classes with all of their responsive variants.&lt;/p&gt;

&lt;p&gt;By default, here are the utility classes that are generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;css
.-order-1 {
  order: -1;
}
.order-0 {
  order: 0;
}
.order-1 {
  order: 1;
}
.order-2 {
  order: 2;
}
.order-3 {
  order: 3;
}
.order-4 {
  order: 4;
}
.order-5 {
  order: 5;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  It is best to avoid using &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; and extract everything into components
&lt;/h2&gt;

&lt;p&gt;Adam Wathan (Tailwind’s creator), said this in a tweet:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Confession: The apply feature in Tailwind only exists to trick people who are put off by long lists of classes into trying the framework. You should almost never use it. Reuse your utility-littered HTML instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a nutshell, this can result in maintainability issues. I built several projects, and I seldom had to rely on them. So trust me, this is possible!&lt;/p&gt;

&lt;p&gt;If you are using a framework like Vue.js or React (where you define everything as components), it will be simple to avoid using the &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; feature. I rarely (if ever) use it.&lt;/p&gt;

&lt;p&gt;I also have another reason for not using it much: I find it easier to debug the code when I only use the utility classes in my code. You can see which style is applied to each tag as you only have one place where your team can control the style (i.e., the classes).&lt;/p&gt;

&lt;p&gt;So, use the &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; feature carefully so you can save yourself some time in the long run!&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Clone an array in ES 6</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Sun, 07 Aug 2022 23:46:49 +0000</pubDate>
      <link>https://dev.to/joseprest/clone-an-array-in-es-6-4aj3</link>
      <guid>https://dev.to/joseprest/clone-an-array-in-es-6-4aj3</guid>
      <description>&lt;p&gt;When we need to copy an array, we often times used slice. But with ES6, you can also use the spread operator to duplicate an array. Pretty nifty, right 🤩&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sheeps = ['🐑', '🐑', '🐑'];

// Old way
const cloneSheeps = sheeps.slice();

// ES6 way
const cloneSheepsES6 = [...sheeps];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Can’t I Use = to Copy an Array?
&lt;/h2&gt;

&lt;p&gt;Because arrays in JS are reference values, so when you try to copy it using the = it will only copy the reference to the original array and not the value of the array. To create a real copy of an array, you need to copy over the value of the array under a new value variable. That way this new array does not reference to the old array address in memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sheeps = ['🐑', '🐑', '🐑'];

const fakeSheeps = sheeps;
const cloneSheeps = [...sheeps];

console.log(sheeps === fakeSheeps);
// true --&amp;gt; it's pointing to the same memory space

console.log(sheeps === cloneSheeps);
// false --&amp;gt; it's pointing to a new memory space
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Problem with Reference Values
&lt;/h2&gt;

&lt;p&gt;If you ever dealt with Redux or any state management framework. You will know immutability is super important. Let me briefly explain. An immutable object is an object where the state can't be modified after it is created. The problem with JavaScript is that arrays are mutable. So this can happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sheeps = ['🐑', '🐑'];

const sheeps2 = sheeps;

sheeps2.push('🐺');

console.log(sheeps2);
// [ '🐑', '🐑', '🐺' ]

// Ahhh 😱 , our original sheeps have changed?!
console.log(sheeps);
// [ '🐑', '🐑', '🐺' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's why we need to clone an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sheeps = ['🐑', '🐑'];

const sheeps2 = [...sheeps];

// Let's change our sheeps2 array
sheeps2.push('🐺');

console.log(sheeps2);
// [ '🐑', '🐑', '🐺' ]

// ✅ Yay, our original sheeps is not affected!
console.log(sheeps);
// [ '🐑', '🐑' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mutable vs Immutable Data Types
&lt;/h2&gt;

&lt;p&gt;Mutable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;object&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Immutable:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All primitives are immutable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;undefined&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;symbol&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Shallow Copy Only
&lt;/h2&gt;

&lt;p&gt;Please note spread only goes one level deep when copying an array. So if you're trying to copy a multi-dimensional arrays, you will have to use other alternatives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nums = [[1, 2], [10]];

const cloneNums = [...nums];

// Let's change the first item in the first nested item in our cloned array.
cloneNums[0][0] = '👻';

console.log(cloneNums);
// [ [ '👻', 2 ], [ 10 ], [ 300 ] ]

// NOOooo, the original is also affected
console.log(nums);
// [ [ '👻', 2 ], [ 10 ], [ 300 ] ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an interesting thing I learned. Shallow copy means the first level is copied, deeper levels are referenced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community Input
&lt;/h2&gt;

&lt;p&gt;Array.from is Another Way to Clone Array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sheeps = ['🐑', '🐑', '🐑'];

const cloneSheeps = Array.from(sheeps);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Using v-model with objects for custom components</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Thu, 28 Jul 2022 16:20:00 +0000</pubDate>
      <link>https://dev.to/joseprest/using-v-model-with-objects-for-custom-components-5bhp</link>
      <guid>https://dev.to/joseprest/using-v-model-with-objects-for-custom-components-5bhp</guid>
      <description>&lt;p&gt;Components are the most powerful feature of Vue.js. They allow you to structure an app as small, reusable units which you can use again to compose new features.&lt;/p&gt;

&lt;p&gt;While building SimpleSell, I needed custom components that bundle a bunch of input fields. They should behave like reusable input controls, while their state is provided by an object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basics of v-model
&lt;/h3&gt;

&lt;p&gt;Of course you know v-model, the attribute which makes most of your input elements working. But did you know that you can use v-model as an interface for own components, too?&lt;/p&gt;

&lt;p&gt;For a better understanding let's have a look at some basics.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;input type="text" v-model="value"&amp;gt;&lt;/code&gt;&lt;br&gt;
v-model is nothing more than syntactical sugar for the following.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;input type="text" :value="value" @input="e =&amp;gt; value = e.target.value"&amp;gt;&lt;/code&gt;&lt;br&gt;
First we have the :value binding. It supplies the value of the input field. Second there is the @input event. As soon as there is an input event fired, we update the model's data property value with the current value of the input element. You also can use the abbreviation: @input="value = $event.target.value".&lt;/p&gt;

&lt;p&gt;Wrapping an input field in a custom component&lt;br&gt;
So let's create a small CreateCustomer.vue component which is nothing more than a wrapped input element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;input type="text" :value="value" @input="$emit('input', $event.target.value)"&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
  props: ['value'],
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We bind the value that we get from the parent component to the text input and for @input we emit an input event with the field's current value to the parent. The next snippet shows the usage of the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;template&amp;gt;
  &amp;lt;CreateCustomer v-model="name"&amp;gt;&amp;lt;/CreateCustomer&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import CreateCustomer from './CreateCustomer'   

export default {
  components: { CreateCustomer },
  data() {
    return {
      name: 'John Doe',
    }
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using an object with v-model&lt;br&gt;
As soon as we add more input elements and want to use an object as value for v-model, things get a bit more complicated. I found this issue on GitHub where Evan You from Vue.js provides an example how v-model is supposed to work with objects.&lt;/p&gt;

&lt;p&gt;Basically every data update of the component has to $emit a completely new instance of the object which then replaces the object instance stored in the parent's data. Otherwise you will get pretty strange and hard to debug behavior (e.g. watchers are not working properly) because objects are passed by reference in JavaScipt.&lt;/p&gt;

&lt;p&gt;At first glance this sounds very complicated but actually it isn't. You have to create a (deep) clone of the object, change values only on the clone and $emit that object.&lt;/p&gt;

&lt;p&gt;Let's extend our CreateCustomer component with a second input, a select for the contact type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
      &amp;lt;input type="text" :value="value.name" @input="update('name', $event.target.value)"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Type&amp;lt;/label&amp;gt;
      &amp;lt;select :value="value.type" @input="update('type', $event.target.value)"&amp;gt;
        &amp;lt;option value="Person"&amp;gt;Person&amp;lt;/option&amp;gt;
        &amp;lt;option value="Company"&amp;gt;Company&amp;lt;/option&amp;gt;
      &amp;lt;/select&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
  props: ['value'],
  methods: {
    update(key, value) {
      this.$emit('input', { ...this.value, [key]: value })
    },
  },
}
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Now that we have two fields we use an object as argument for v-model for the first time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;CreateCustomer v-model="{ name: 'John Doe', type: 'Person' }"&amp;gt;&amp;lt;/CreateCustomer&amp;gt;&lt;/code&gt;&lt;br&gt;
For the :value bindings just use the object's properties. For the @input I created a method which emits the input event with a shallow clone of the object and sets the new value for the given key. Remember you can use object destructuring for shallow cloning of objects since ES6.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using an object with v-model
&lt;/h3&gt;

&lt;p&gt;As soon as we add more input elements and want to use an object as value for v-model, things get a bit more complicated. I found this issue on GitHub where Evan You from Vue.js provides an example how v-model is supposed to work with objects.&lt;/p&gt;

&lt;p&gt;Basically every data update of the component has to $emit a completely new instance of the object which then replaces the object instance stored in the parent's data. Otherwise you will get pretty strange and hard to debug behavior (e.g. watchers are not working properly) because objects are passed by reference in JavaScipt.&lt;/p&gt;

&lt;p&gt;At first glance this sounds very complicated but actually it isn't. You have to create a (deep) clone of the object, change values only on the clone and $emit that object.&lt;/p&gt;

&lt;p&gt;Let's extend our CreateCustomer component with a second input, a select for the contact type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
      &amp;lt;input type="text" :value="value.name" @input="update('name', $event.target.value)"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Type&amp;lt;/label&amp;gt;
      &amp;lt;select :value="value.type" @input="update('type', $event.target.value)"&amp;gt;
        &amp;lt;option value="Person"&amp;gt;Person&amp;lt;/option&amp;gt;
        &amp;lt;option value="Company"&amp;gt;Company&amp;lt;/option&amp;gt;
      &amp;lt;/select&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
  props: ['value'],
  methods: {
    update(key, value) {
      this.$emit('input', { ...this.value, [key]: value })
    },
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have two fields we use an object as argument for v-model for the first time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;CreateCustomer v-model="{ name: 'John Doe', type: 'Person' }"&amp;gt;&amp;lt;/CreateCustomer&amp;gt;&lt;/code&gt;&lt;br&gt;
For the :value bindings just use the object's properties. For the @input I created a method which emits the input event with a shallow clone of the object and sets the new value for the given key. Remember you can use object destructuring for shallow cloning of objects since ES6.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using v-model with null
&lt;/h3&gt;

&lt;p&gt;Maybe there is the case where we default the v-model value with null in our parent component because we don't know if our CreateCustomer form is actually used. If we pass null we get an error because we can't access object properties on null. In addition the consumer shouldn't know that the component only works if at least an empty object is passed to v-model.&lt;/p&gt;

&lt;p&gt;Second, we need a default value for type. Otherwise the select shows an invalid empty option at the top.&lt;/p&gt;

&lt;p&gt;I struggled a lot with this problem and thankfully Adam Wathan helped me out. (Check out his upcoming Advanced Vue Component Design course, I highly recommend it!)&lt;/p&gt;

&lt;p&gt;He suggested to use computed properties. So let's refactor our component again and add a computed property local which returns the value if there is one, otherwise an object with appropriate defaults.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
      &amp;lt;input type="text" :value="local.name" @input="update('name', $event.target.value)"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Type&amp;lt;/label&amp;gt;
      &amp;lt;select :value="local.type" @input="update('type', $event.target.value)"&amp;gt;
        &amp;lt;option value="Person"&amp;gt;Person&amp;lt;/option&amp;gt;
        &amp;lt;option value="Company"&amp;gt;Company&amp;lt;/option&amp;gt;
      &amp;lt;/select&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
  props: ['value'],
  computed: {
    local() {
      return this.value ? this.value : { type: 'Person' }
    },
  },
  methods: {
    update(key, value) {
      this.$emit('input', { ...this.local, [key]: value })
    },
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be aware that we only use this.value in our computed property local. Everywhere else we use this.local instead of this.value. So if we're getting a null value, we're working with our defaults and thus prevent weird errors.&lt;/p&gt;

&lt;p&gt;Using a nested object with v-model&lt;br&gt;
Let's take it a step further. Suppose we have a data model like the following for our CreateCustomer component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  name: 'John Doe',
  type: 'Person',
  address: {
    street: 'Example Street 42',
    zip: '12345',
    city: 'Example City'
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added a nested object address. Basically there are two options to extend our component:&lt;/p&gt;

&lt;p&gt;Create a custom component CustomerAddress and use the patterns shown above. Then there would be one responsible component per level of nesting in the data model (which is a good recommendation anyway).&lt;br&gt;
Embed it into our component.&lt;br&gt;
We take the second, more complex approach so I can give you deeper insight into using nested objects with v-model.&lt;/p&gt;

&lt;p&gt;To keep things simple, I removed some fields and only add a new input for address.street.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
      &amp;lt;input type="text" :value="local.name" @input="update('name', $event.target.value)"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- ... --&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;label&amp;gt;Street&amp;lt;/label&amp;gt;
      &amp;lt;input type="text" :value="local.address.street" @input="update('address.street', $event.target.value)"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- inputs for zip and city work the same way --&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import { cloneDeep, tap, set } from 'lodash'

export default {
  props: ['value'],
  computed: {
    local() {
      return this.value ? this.value : { type: 'Person', address: {} }
    },
  },
  methods: {
    update(key, value) {
      this.$emit('input', tap(cloneDeep(this.local), v =&amp;gt; set(v, key, value)))
    },
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're dealing with a nested object, so we bind local.address.street as our input's value. Remember to add address: {} to the local computed property to prevent null pointers.&lt;/p&gt;

&lt;p&gt;Since there is no native JavaScript function for deep cloning an object I've imported some functions from Lodash.&lt;/p&gt;

&lt;p&gt;cloneDeep(value): Creates a deep clone of the value.&lt;br&gt;
tap(value, callback): Returns value after passing it to callback. Used to create a functional expressive one-liner function ;-)&lt;br&gt;
set(object, path, value): Sets a nested value on an object, specified by a path in dot notation, e.g. set({}, 'address.street', 'Example Street 42') yields { address: { street: 'Example Street 42' } }.&lt;br&gt;
The update method accepts a property path as key, creates a deep clone of our local computed value and sets the new value at the right property path. Setting nested values becomes as simple as @input="update('address.street', $event.target.value)".&lt;/p&gt;
&lt;h3&gt;
  
  
  Working with nested arrays
&lt;/h3&gt;

&lt;p&gt;Let's consider we want to store a list of contact items for every customer with the option to add and delete them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
  name: 'John Doe',
  type: 'Person',
  address: {
    street: 'Example Street 42',
    zip: '12345',
    city: 'Example City'
  },
  contacts: [
    { type: 'Email', value: 'john@example.com' },
    { type: 'Phone' value: '+1234567890' }
  ]
}
So we extend our component for a last time.

&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;!-- ... --&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Type&amp;lt;/label&amp;gt;
        &amp;lt;select v-model="newContactType"&amp;gt;
          &amp;lt;option value="Phone"&amp;gt;Phone&amp;lt;/option&amp;gt;
          &amp;lt;option value="Email"&amp;gt;Email&amp;lt;/option&amp;gt;
        &amp;lt;/select&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Value&amp;lt;/label&amp;gt;
        &amp;lt;input type="text" v-model="newContactValue"&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;button type="button" @click="addContact"&amp;gt;Add&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div v-for="(contact, i) in local.contacts"&amp;gt;
      {{ contact.type }} {{ contact.value }}
      &amp;lt;button type="button" @click="removeContact(i)"&amp;gt;Remove&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import { cloneDeep, tap, set } from 'lodash'

export default {
  props: ['value'],
  data() {
    return {
      newContactType: 'Email',
      newContactValue: null,
    }
  },
  computed: {
    local() {
      return this.value ? this.value : { type: 'Person', address: {}, contacts: [] }
    },
  },
  methods: {
    // ...
    addContact() {
      this.$emit('input', tap(cloneDeep(this.customer), v =&amp;gt; v.contacts.push({ 
        type: this.newContactType,
        value: this.newContactValue,
      })))
    },
    removeContact(i) {
      this.$emit('input', tap(cloneDeep(this.customer), v =&amp;gt; v.contacts.splice(i, 1)))
    },
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the logic needed to add a new contact item, v-model is used directly because it's only about local state in our component that shouldn't be propagated to the parent. Remember to add contacts: [] to the local computed property to use an empty array as default. Only if the add or delete button is clicked, a new input event is emitted with a deep clone of the object including the array's changes.&lt;/p&gt;

&lt;p&gt;$emit initial state from the created hook&lt;br&gt;
Of course you can use the update method in the created hook, too. Use it to set component's defaults at its instantiation and propagate them to the parent instantly. Be aware that you should only use one update or $emit and set the initial state at once to prevent unexpected executions of watchers and timing issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
export default {
  created() {
    this.$emit('input', tap(cloneDeep(this.local), v =&amp;gt; {
      v.type = 'Company'
      v.address.city = 'Example City'
      v.contacts.push({ type: 'Email' })
    }))
  },
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've explained a lot of concepts in this post. Of course you should not use those patterns for every component you build. Sometimes it's better to just decompose complex components into smaller ones which are easier to work with and to reason about.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>VS Code emmet tips to make you more productive</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Mon, 11 Jul 2022 02:39:48 +0000</pubDate>
      <link>https://dev.to/joseprest/vs-code-emmet-tips-to-make-you-more-productive-2pla</link>
      <guid>https://dev.to/joseprest/vs-code-emmet-tips-to-make-you-more-productive-2pla</guid>
      <description>&lt;p&gt;In general, productivity is the ratio between output and input. In software engineering, programming productivity(or development productivity) can be the ratio between the quantity of the software code produced and its time cost.&lt;br&gt;
In mathematical terms,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Development Productivity = Quantity of Software Code / (Number of Programmers * Time Spent to Produce the Code)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The lesser time spent to produce the code results in a significant increase in the development productivity. Let us learn about a few tips &amp;amp; tricks to drastically reduce the HTML/CSS source code creation time to become super productive.&lt;/p&gt;
&lt;h2&gt;
  
  
  VS Code and Emmet
&lt;/h2&gt;

&lt;p&gt;Visual Studio Code(aka, VS Code) is one of the leading source code editors (also an IDE) and arguably one of the best today for web development. Emmet is a plug-in-based infrastructure that can produce HTML/CSS code snippets from short-hand syntaxes. VS Code supports Emmet 2.0 out of the box. It means you do not need any additional extensions to take advantage of it.&lt;/p&gt;

&lt;p&gt;Let us see ten such usages of the emmet using VS code to help you become a more productive developer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feel free to open an empty HTML file in the VS Code editor and try out these tips &amp;amp; tricks as you read!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  1. HTML Structure and Tags
&lt;/h3&gt;

&lt;p&gt;One of the struggles that most web developers face is remembering the HTML Structure and syntaxes of HTML tags. What could be more exciting than a single character can create the basic HTML structure for us? Open an empty HTML file using VS code and type the ! character. You will get an option to select to create a basic HTML structure, as shown in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gQ4EyvcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glew3ompzptruewzh1di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gQ4EyvcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glew3ompzptruewzh1di.png" alt="Image description" width="600" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can type a few initial letters of any HTML tags to create elements with the required attributes. The image below shows the possibilities to create the anchor tag with different attributes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wfJb7O7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvw2pzw2n7rno7ul50bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wfJb7O7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvw2pzw2n7rno7ul50bd.png" alt="Image description" width="599" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are a few more examples that are of frequent use in web development. We can link to a CSS file, load a JavaScript file, create different input tags, a disabled button, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X2vnfMoF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g8iwrtiqp7ipi5ugp4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X2vnfMoF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g8iwrtiqp7ipi5ugp4i.png" alt="Image description" width="600" height="298"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;There are plenty of others you can try out by typing the initial characters of the HTML tags.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Add class and id
&lt;/h3&gt;

&lt;p&gt;An efficient way to reduce coding time is to create HTML tags with the required class names and ids. Try this shortcut to create a ul tag with the class name, list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ul.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul class="list"&amp;gt;&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, here is the shortcut for creating a ul element with the id, list-id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ul#list-id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul id="list-id"&amp;gt;&amp;lt;/ul&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;If you want to add a class name or id to the div element, you do not even need to mention the div in the shorthand.&lt;/p&gt;

&lt;p&gt;For class name,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="content"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For id,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#content-id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="content-id"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Children
&lt;/h3&gt;

&lt;p&gt;Creating a nested HTML structure manually can be very tedious. What if we can create the nested HTML structure by typing only a few characters? Let's create an unordered list(ul) and a list item(li) under it. Use the &amp;gt; symbol to create the nested child structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ul&amp;gt;li
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lorem is another useful shortcut to create some random texts to test your web page faster. Let's create a paragraph(p) tag with the Lorem texts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p&amp;gt;Lorem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Lorem ipsum dolor sit amet consectetur, adipisicing elit. Consectetur deserunt quam voluptatum quos ipsa cupiditate ipsum qui sequi illum? Qui exercitationem accusamus totam natus ut fugit magnam modi eaque doloremque.&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let us create an unordered list(ul) with a list item(li) under it. The list item should have a class name, list. Finally, we want to create an anchor(a) tag with a class name, link inside the li tag.&lt;br&gt;
&lt;code&gt;ul&amp;gt;li.list&amp;gt;a.link&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &amp;lt;li class="list"&amp;gt;
       &amp;lt;a href="" class="link"&amp;gt;&amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Multiplication
&lt;/h3&gt;

&lt;p&gt;You can multiply an HTML element using the * symbol. Let's create 5 list tags(li) inside a ul tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ul&amp;gt;li*5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Siblings
&lt;/h3&gt;

&lt;p&gt;Use the + symbol to create multiple elements at the same level. Let's say we want to create three div elements in the same level wrapped by another div.&lt;br&gt;
&lt;code&gt;.bothers&amp;gt;.alex+.bob+.me&lt;/code&gt;&lt;br&gt;
produces&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="bothers"&amp;gt;
    &amp;lt;div class="alex"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="bob"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="me"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you know by now, we do not need to mention the div element when creating it with class name and id.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Grouping
&lt;/h3&gt;

&lt;p&gt;Once you know the usages of the last 5 tips &amp;amp; tricks, you can use them in combinations to become very productive. This is where the grouping comes in to picture. We use the ( symbol along with ) to create the group.&lt;/p&gt;

&lt;p&gt;Let's create a ul tag and 5 groups of li and a tags.&lt;br&gt;
&lt;code&gt;ul&amp;gt;(li&amp;gt;a)*5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;produces&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=""&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=""&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=""&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=""&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=""&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let us take a bit more complex usage. Notice the grouping used in the short-hand below,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;div&amp;gt;(header&amp;gt;ul&amp;gt;li*2&amp;gt;span.item)+section.content+(footer&amp;gt;(p&amp;gt;Lorem)*2)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once you break it down, it creates the proper nested structure using the group. The image below demonstrates it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yAvb7CeI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hj0c1jne07y7f12jkeja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yAvb7CeI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hj0c1jne07y7f12jkeja.png" alt="Image description" width="501" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It produces this code snippet,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    &amp;lt;header&amp;gt;
        &amp;lt;ul&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;span class="item"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;span class="item"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/header&amp;gt;
    &amp;lt;section class="content"&amp;gt;&amp;lt;/section&amp;gt;
    &amp;lt;footer&amp;gt;
        &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat iure quaerat, molestias dolore commodi sequi porro, delectus eius quos saepe recusandae veniam modi laudantium voluptatibus cumque odit similique beatae eos.&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;Nemo sequi veniam est! Laborum rem iste id vel, harum repellendus, reiciendis labore minima eum voluptatem dicta error nesciunt fugiat! Ipsa, perferendis iste exercitationem explicabo ex consequuntur dicta iure ipsam.&amp;lt;/p&amp;gt;
    &amp;lt;/footer&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Numbering
&lt;/h3&gt;

&lt;p&gt;We use the $ symbol to create numbering. we can use the $ symbol with the * to multiply the number of occurrences.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;header&amp;gt;ul&amp;gt;li.item$*3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;produces&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li class="item1"&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li class="item2"&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li class="item3"&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
&amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Text
&lt;/h3&gt;

&lt;p&gt;We use the flower braces({ and }) to create elements with the text within them. Let's create a span element with some text within it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;span{I am a span}&lt;/code&gt;&lt;br&gt;
produces,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;span&amp;gt;I am a span&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ok, how to create all the HTML heading tags(H1...H6) with the text identifying them? Here is the short-hand for it,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;h$*6{I'm a Heading $}*6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;I'm a Heading 1&amp;lt;/h1&amp;gt;
&amp;lt;h2&amp;gt;I'm a Heading 2&amp;lt;/h2&amp;gt;
&amp;lt;h3&amp;gt;I'm a Heading 3&amp;lt;/h3&amp;gt;
&amp;lt;h4&amp;gt;I'm a Heading 4&amp;lt;/h4&amp;gt;
&amp;lt;h5&amp;gt;I'm a Heading 5&amp;lt;/h5&amp;gt;
&amp;lt;h6&amp;gt;I'm a Heading 6&amp;lt;/h6&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. Climb up
&lt;/h3&gt;

&lt;p&gt;You may feel a need to climb back to the HTML tree when you are too deep nested down. You can use the ^ symbol to climb up a step in the hierarchy. You can use the symbol multiple times to climb up multiple steps. Let's understand with examples.&lt;/p&gt;

&lt;p&gt;Here we are adding a div tag by climbing up once.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;div&amp;gt;div&amp;gt;h3+span^div{I can climb up}&lt;/code&gt;&lt;br&gt;
produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;I can climb up&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the placement of the div tag when we climb twice!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;div&amp;gt;div&amp;gt;h3+span^^div{I can climb up}&lt;/code&gt;&lt;br&gt;
produces,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;I can climb up&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;CSS
We have an ocean of opportunities here. You can use the short-hands in the CSS file to generate the CSS properties. Here are a few I use very often,
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EYe3nG57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol36pyrrdif0ixnt1uy9.png" alt="Image description" width="596" height="300"&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>vscode</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Run Ngrok to Test &amp; Share Your Local Development</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Sun, 24 Apr 2022 01:34:02 +0000</pubDate>
      <link>https://dev.to/joseprest/how-to-run-ngrok-to-test-share-your-local-development-knj</link>
      <guid>https://dev.to/joseprest/how-to-run-ngrok-to-test-share-your-local-development-knj</guid>
      <description>&lt;p&gt;One traditional pain point in software development is the need to continuously redeploy work to a remote web server to test functionality, compatibility and share with collaborators. Maybe you need to show your team a quick demo of something you’ve been working on, or test webhook notifications with integrated third-party services. Traditional ways to make the necessary link up can be complex and time consuming - not suitable just for sharing or testing something quickly. Luckily, there is an easy plug-and-play solution available: Ngrok.&lt;/p&gt;

&lt;p&gt;Ngrok is, in the words of its founder Alan Shreve, “a tunneling, reverse proxy that establishes secure tunnels from a public endpoint to a locally running network service while capturing all traffic for inspection and replay”. In other words, it’s a cross-platform utility that allows developers to expose a local development server to the internet with minimal fuss. This enables quick and easy testing of add-ons and webhooks directly from your local machine. &lt;/p&gt;

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

&lt;p&gt;The basic function of Ngrok is to expose a local web server to the internet via a secure tunnel. The free version of the tool does this by generating a random URL hostname (like abcde123.Ngrok.com) that is connected to the internet and can route requests and notifications from third-party apps to your local machine. By default, Ngrok will forward both HTTP and HTTPS traffic to your local machine, so there are no problems when testing webhooks with third-party services that require SSL certificates, domain validation, etc. &lt;/p&gt;

&lt;p&gt;Ngrok also provides a real-time web UI where you can track all of the HTTP traffic running over your tunnels. It has a web console for this that is easy to access in your browser by opening (&lt;a href="http://localhost:4040" rel="noopener noreferrer"&gt;http://localhost:4040&lt;/a&gt;). Through the console, you can inspect requests and responses, as well as replay API requests with a single click. This can help speed up iteration testing by saving you the work usually required to generate new requests.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F623fz2bufidicvnbnjtb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F623fz2bufidicvnbnjtb.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
 We’ve written before about why Laravel is the go-to framework for many PHP developers. As a framework, it’s simple to use and offers a wide range of libraries, tools, and templates to help developers build complex and stable web applications. But developers usually work in teams, so they need to be able to share or present a demo of their local framework with colleagues. Enter Ngrok.  &lt;/p&gt;

&lt;p&gt;Ngrok and Laravel are a great fit for each other. As we’ve shown, Ngrok allows you to quickly create a tunnel for free and Laravel has an internal web server that can be used without configuration. As a developer, this makes it really easy to share your local Laravel framework with anyone that uses a browser. &lt;/p&gt;

&lt;p&gt;To show you just how easy, here we explain in three steps how to run Ngrok on Mac/Windows/Linux and share your Laravel Framework Installation with anyone outside your network (Note: These steps assume you already have Laravel correctly installed on your local machine).&lt;/p&gt;

&lt;h3&gt;
  
  
  Download and Prepare Ngrok
&lt;/h3&gt;

&lt;p&gt;First, download the Ngrok binary. Choose your OS (Mac, Windows or a Linux Distro). &lt;/p&gt;

&lt;p&gt;Then locate the downloaded file, unzip it and move it to a place available on the PATH (you need sudo credentials). In Windows, you can unzip directly by clicking on the file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

unzip /path/to/ngrok.zip
sudo mv /path/to/ngrok /usr/local/bin/ 


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

&lt;/div&gt;

&lt;p&gt;After this, you can get Ngrok running from the command line by telling it which port to connect to. The HTTP default is 80 so the command here would be:&lt;br&gt;
&lt;code&gt;ngrok http 80&lt;/code&gt;&lt;br&gt;
Though it is not required to use the basic version of Ngrok, if you register an account you can install an auth token that will grant you access to more advanced features (see below). &lt;/p&gt;

&lt;p&gt;Additional info is available on the &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;Ngrok website&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serve your Laravel Installation
&lt;/h3&gt;

&lt;p&gt;Open a console window. Go to your local Laravel Installation and turn on the artisan server. We will be using 127.0.0.1 instead of localhost (default).&lt;/p&gt;

&lt;p&gt;Leave the console and the artisan server process running. This is the Webserver listening for requests.&lt;/p&gt;

&lt;p&gt;Additional info: &lt;a href="https://laravel.com/" rel="noopener noreferrer"&gt;Laravel Framework&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Share your Laravel installation!
&lt;/h3&gt;

&lt;p&gt;Open an extra console window and run Ngrok:&lt;br&gt;
&lt;code&gt;ngrok 8000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should see something like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Tunnel Status                 online
Version                       1.7/1.6
Forwarding                    http://284abb77.ngrok.com -&amp;gt; 127.0.0.1:8000


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

&lt;/div&gt;

&lt;p&gt;This is the URL that you can share with anyone you want: &lt;a href="http://284abb77.Ngrok.com" rel="noopener noreferrer"&gt;http://284abb77.Ngrok.com&lt;/a&gt;. The user accessing it will see your Laravel Installation running at 127.0.0.1:8000.&lt;/p&gt;

&lt;p&gt;And that’s it! Just remember to turn off Ngrok when you want to stop sharing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some Additional Ngrok Features
&lt;/h3&gt;

&lt;p&gt;Ngrok is an open-source, free software tool that anyone can use. But if you register for an account and/or sign up for a paid plan you can unlock more advanced features. These include:&lt;/p&gt;

&lt;h4&gt;
  
  
  Customized and reserved domains:
&lt;/h4&gt;

&lt;p&gt;These include the ability to reserve a specific domain name that will remain exclusive to you and your team. You can also specify a custom subdomain for your Ngrok tunnel and protect it with a password. &lt;/p&gt;

&lt;h4&gt;
  
  
  Multiple tunnels:
&lt;/h4&gt;

&lt;p&gt;You can run multiple tunnels simultaneously through Ngrok. You can define tunnel configurations on a simple YAML configuration file and then start them just by entering the saved names as a command.  You can even start all the tunnels defined in the configuration file with the following command:&lt;br&gt;
&lt;code&gt;ngrok start --all&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Greater control and security:
&lt;/h4&gt;

&lt;p&gt;Other paid-for solutions include the ability to whitelist IP access to your tunnels, thereby ensuring no unknown party can connect to your tunnel endpoints.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tailwind CSS best practices</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Thu, 14 Apr 2022 01:56:25 +0000</pubDate>
      <link>https://dev.to/joseprest/tailwind-css-best-practices-37k9</link>
      <guid>https://dev.to/joseprest/tailwind-css-best-practices-37k9</guid>
      <description>&lt;h3&gt;
  
  
  Utility classes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When writing a string of multiple utility classes, always do so in an order with meaning. The "Concentric CSS" approach works well with utility classes (i.e,. 1. positioning/visibility 2. box model 3. borders 4. backgrounds 5. typography 6. other visual adjustments). Once you establish a familiar pattern of ordering, parsing through long strings of utility classes will become much, much faster so a little more effort up front goes a long way!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always use fewer utility classes when possible. For example, use mx-2 instead of ml-2 mr-2 and don't be afraid to use the simpler p-4 lg:pt-8 instead of the longer, more complicated pt-4 lg:pt-8 pr-4 pb-4 pl-4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prefix all utility classes that will only apply at a certain breakpoint with that breakpoint's prefix. For example, use block lg:flex lg:flex-col lg:justify-center instead of block lg:flex flex-col justify-center to make it very clear that the flexbox utilities are only applicable at the lg: breakpoint and larger.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keep in mind that, by default, all responsive utilities are set to apply at min-width. That is, the sm: prefix does not apply only to small viewports; it applies to small breakpoints and larger. So for example instead of using the longform block sm:block md:flex lg:flex xl:flex for a &lt;/p&gt; element you can just write md:flex. They both have the same behavior.
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also note that, by default, the sm: breakpoint does not start at min-width: 0 as you might expect. It starts at min-width: 640px. So if you want something to apply only to the smallest of viewports (those smaller than 640px), you must first set it to apply to all breakpoints and then override it for larger breakpoints. For example, use block sm:inline if you want something to appear as block for only the smallest of screens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a consistent pattern of margin classes to make it easier to reason about positioning. For example, consistently use only mt-* and ml-* utilities, which will position the current element, or consistently use only mb-* and mr-* utilities, which will position adjacent elements. In general it is easier to reason about positioning when using the former pattern because it is effectively scoped to the styled element, but keep in mind that you may need to make exceptions to your selected pattern for elements which only appear under certain conditions, as you wouldn't want to have to also add conditional margins to elements that are adjacent to the conditional element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remember that you can often add a wrapper &lt;/p&gt; with padding instead of using margins, which may help avoid potential issues with margin collapsing. By using utility-first CSS, you don't need to invent "semantic" class names for single purpose s so there is no reason to avoid using them when they are helpful.

&lt;h3&gt;
  
  
  Component classes
&lt;/h3&gt;

&lt;p&gt;Do not prematurely use @apply to abstract component classes where a proper framework/template-based component is more appropriate. However, if the string of utility classes within that component is also used in other components, then there is true duplication. In this case, the creation of a new shared CSS component class with @apply may be warranted.&lt;/p&gt;

&lt;p&gt;Do not @apply component classes in other components. For example, maintain seperate .btn and .btn-blue classes rather than using &lt;code&gt;.btn-blue { @apply btn; }&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Dynamic classes
&lt;/h3&gt;

&lt;p&gt;When CSS classes are selected or generated dynamically, do not use string concatination to combine fragments of the full class. Instead switch between the complete strings. For example, use this &lt;code&gt;{% set width = maxPerRow == 2 ? 'sm:w-1/2' : 'sm:w-1/3' %}&lt;/code&gt; instead of this &lt;code&gt;{% set width = 'sm:w-1/' ~ maxPerRow %}&lt;/code&gt;. You always want the complete string of each utility class present in the markup to make it easier to reason about and to ensure that it survives the PurgeCSS process, if it is a part of your build tools.&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
    </item>
    <item>
      <title>Test react-hook-form with react-native-testing-library</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Thu, 14 Apr 2022 01:52:20 +0000</pubDate>
      <link>https://dev.to/joseprest/test-react-hook-form-with-react-native-testing-library-4a5o</link>
      <guid>https://dev.to/joseprest/test-react-hook-form-with-react-native-testing-library-4a5o</guid>
      <description>&lt;p&gt;I use react-hook-form for both web and react native without a single problem. Great library. When using react-hook-form v6. I encountered an issue where the validation works perfectly in code, but in test, the errors object is always empty even for wrong value. Let’s see how to solve it. In this blog, I will demostrate how to test react-hook-form with react-native-testing-library for both iOS and Android within one test through jest-expo, and yes, we will use jest as the test runner.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setup the project
&lt;/h2&gt;

&lt;p&gt;I will use expo for a quick demonstration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# select blank template, JS or TS
expo init test-rhf

cd test-rhf
yarn add react-hook-form
yarn add --dev react-native-testing-library jest-expo

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

&lt;/div&gt;



&lt;p&gt;jest-expo is a library from the Expo team to do universal testing here, it will run your tests for every platform you setup, here, because react-native-testing-library only supports native device, we will not use web setup, via expo‘s file extension pick up and the similarities between react-native-testing-library and @testing-library/react, share one single test file for both web and native devices should be easy, will try them later.&lt;/p&gt;

&lt;p&gt;In package.json:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;add a script: "test": "node_modules/.bin/jest"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add jest settings:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"jest": {
    "projects": [
      {
        "preset": "jest-expo/ios",
        "setupFilesAfterEnv": [
          "&amp;lt;rootDir&amp;gt;/jestAfterEnvSetup.js"
        ]
      },
      {
        "preset": "jest-expo/android",
        "setupFilesAfterEnv": [
          "&amp;lt;rootDir&amp;gt;/jestAfterEnvSetup.js"
        ]
      }
    ]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to rewrite any jest rules, you have to write the new rule for each platform like the above example.&lt;/p&gt;

&lt;p&gt;create jestAfterEnvSetup.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global.window = {};
global.window = global;

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

&lt;/div&gt;



&lt;p&gt;If you are using Typescript, you might need to // @ts-ignore the above lines&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The application to test
&lt;/h2&gt;

&lt;p&gt;Change App.js to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { Text, Button, TextInput, View } from "react-native";
import { useForm, Controller } from "react-hook-form";

export default function App() {
  const { errors, control, handleSubmit } = useForm({
    defaultValues: { name: "" },
  });

  const errorText = errors["name"]?.message;
  const isError = Boolean(errorText);

  return (
    &amp;lt;View style={{ margin: 10 }}&amp;gt;
      &amp;lt;Controller
        control={control}
        render={({ onChange, onBlur, value }) =&amp;gt; (
          &amp;lt;TextInput
            style={{ borderColor: "black" }}
            testID="nameInput"
            onChangeText={onChange}
            onBlur={onBlur}
            value={value}
          /&amp;gt;
        )}
        rules={{ required: "name can't be blank" }}
        name="name"
      /&amp;gt;

      {isError &amp;amp;&amp;amp; &amp;lt;Text testID="nameErrorText"&amp;gt;{errorText}&amp;lt;/Text&amp;gt;}

      &amp;lt;Button
        testID="submitButton"
        title="submit"
        onPress={handleSubmit(async ({ name }) =&amp;gt; {
          console.log(name);
        })}
      /&amp;gt;
    &amp;lt;/View&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a simple form here, one text input for name, and it is required, one submit button for submit the values.&lt;/p&gt;

&lt;p&gt;expo start, you will see this ugly application, press the submit button with a blank input will lead to an error.&lt;/p&gt;

&lt;p&gt;We extract the errorText from errors["name"]?.message, than use Boolean(errorText) to check, if there is an error text, then there is an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The test
&lt;/h2&gt;

&lt;p&gt;Create the file App.test.js at the same level of App.js with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from "react";
import App from "./App";
import { render, fireEvent, act } from "react-native-testing-library";

it("should not trigger error for correct values", async () =&amp;gt; {
  const { getByTestId, queryByTestId } = render(&amp;lt;App /&amp;gt;);

  fireEvent.changeText(getByTestId("nameInput"), "ABCDEFG");

  await act(async () =&amp;gt; {
    fireEvent.press(getByTestId("submitButton"));
  });

  expect(queryByTestId("nameErrorText")).not.toBeTruthy();
});

it("should trigger error for empty input", async () =&amp;gt; {
  const { getByTestId, queryByTestId } = render(&amp;lt;App /&amp;gt;);

  await act(async () =&amp;gt; {
    fireEvent.press(getByTestId("submitButton"));
  });

  expect(queryByTestId("nameErrorText")).toBeTruthy();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have 2 tests here, one for happy path, and one for unhappy path.&lt;br&gt;
We will mimic the user’s behaviour.&lt;/p&gt;

&lt;p&gt;For the happy path: If we have a value, the nameErrorText should not been displayed.&lt;br&gt;
For the unhappy path: If we don’t have a value, then the application should show the nameErrorText.&lt;/p&gt;

&lt;p&gt;The test should be quite easy to read. I won’t explain them here.&lt;/p&gt;

&lt;p&gt;The interesting part is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await act(async () =&amp;gt; {
  fireEvent.press(getByTestId("submitButton"));
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why we need to await act(async()=&amp;gt;{}) the pressing button event? It is because the validation in react-hook-form is always async, so you have to wait until it is finished. (Which is good, because real-world validation could be costy).&lt;/p&gt;

&lt;p&gt;If you forget to wrap the act(), you will see a red warning: Warning: An update to App inside a test was not wrapped in act(...)&lt;/p&gt;

&lt;h2&gt;
  
  
  4. End
&lt;/h2&gt;

&lt;p&gt;Run yarn test, you will see all tests pass.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Hope it helps.&lt;/p&gt;

&lt;p&gt;Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>jest</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to listen for mouse wheel events in React?</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Mon, 14 Feb 2022 00:52:54 +0000</pubDate>
      <link>https://dev.to/joseprest/how-to-listen-for-mouse-wheel-events-in-react-2e7</link>
      <guid>https://dev.to/joseprest/how-to-listen-for-mouse-wheel-events-in-react-2e7</guid>
      <description>&lt;p&gt;Sometimes, we want to listen for mouse wheel events in React.&lt;/p&gt;

&lt;p&gt;In this article, we’ll look at how to listen for mouse wheel events in React.&lt;br&gt;
To listen for mouse wheel events in React, we can set the onWheel prop to the mouse wheel event listener.&lt;/p&gt;

&lt;p&gt;For instance, we write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

export default function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;div style={{ height: 600, width: 300 }} onWheel={(e) =&amp;gt; console.log(e)}&amp;gt;
        hello world
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We set onWheel to a function that logs the event object.&lt;/p&gt;

&lt;p&gt;Now when we scroll up and down with the mouse wheel, we should see the event object logged.&lt;br&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
To listen for mouse wheel events in React, we can set the onWheel prop to the mouse wheel event listener.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The advanced guide to React Context with hooks.</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Mon, 14 Feb 2022 00:41:59 +0000</pubDate>
      <link>https://dev.to/joseprest/the-advanced-guide-to-react-context-with-hooks-dh9</link>
      <guid>https://dev.to/joseprest/the-advanced-guide-to-react-context-with-hooks-dh9</guid>
      <description>&lt;p&gt;Hi all,&lt;/p&gt;

&lt;p&gt;It's been almost 4 years when React team has been released hooks, the addition to React function component to use state and control the mounting of the apps via Effects lifecycle method.&lt;/p&gt;

&lt;p&gt;In this guide you'll have a practical guide how to use hooks with Context api (the alternative of redux for small projects [my opinion]).&lt;/p&gt;

&lt;p&gt;Our project is for authentication process, you have to think about it like separate package that you can use for your app and it will handle everything.&lt;/p&gt;

&lt;p&gt;Let's get started....&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Create React app:
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;yarn create react-app my-app --template typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;then create a directory: src/auth&lt;/p&gt;

&lt;h1&gt;
  
  
  2.
&lt;/h1&gt;

&lt;p&gt;we have to ask ourselves what are the things that needed for authentication for now&lt;/p&gt;

&lt;p&gt;Wrapper to wrap our app(Provider).&lt;br&gt;
Component the will inject the props that we need in components tree(Consumer).&lt;br&gt;
Events can be listened from any component tree to auth module.&lt;br&gt;
Couple hooks that makes our life easier 🙂.&lt;/p&gt;

&lt;p&gt;Provider:&lt;br&gt;
We start by creating context that will expose a higher order component called AuthProvider.&lt;/p&gt;

&lt;p&gt;create file under src/auth/AuthContext.ts and fill it with:&lt;/p&gt;

&lt;p&gt;src/auth/AuthContext.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createContext } from "react";

export interface IAuthContext {
  register: (email: string, password: string) =&amp;gt; void;
  login: (email: string, password: string) =&amp;gt; void;
  isAuthenticated: boolean;
}

export const AuthContext = createContext&amp;lt;IAuthContext | undefined&amp;gt;(undefined);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see in the interface that I have defined login, register and isAuthenticated which is the value that we will rely on our app.&lt;/p&gt;

&lt;p&gt;And then create a file you can call it AuthProvider with this content.&lt;/p&gt;

&lt;p&gt;src/auth/AuthProvider.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { ReactElement } from "react";
import { IAuthContext, AuthContext } from "./AuthContext";

interface IAuthProviderProps {
  children: ReactElement&amp;lt;any&amp;gt; | ReactElement&amp;lt;any&amp;gt;[];
}
export function AuthProvider({ children }: IAuthProviderProps) {
  return (
    &amp;lt;AuthContext.Provider
      value={{
        login: () =&amp;gt; {},
        register: () =&amp;gt; {}
        isAuthenticated: false,
      }}
    &amp;gt;
      {children}
    &amp;lt;/AuthContext.Provider&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This a higher order component that can wrap our app which is the children that you pass down and it will check whenever the value is changed and it will render the children again( the normal behaviour of react).&lt;/p&gt;

&lt;p&gt;Now in our app we could wrap like this:&lt;/p&gt;

&lt;p&gt;App.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { render } from "react-dom";
import { AuthProvider } from "./auth/AuthProvider";
import MyComponent from "./MyComponent";

const App = () =&amp;gt; (
  &amp;lt;AuthProvider&amp;gt;
    &amp;lt;MyComponent /&amp;gt;
  &amp;lt;/AuthProvider&amp;gt;
);

render(&amp;lt;App /&amp;gt;, document.getElementById("root"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

interface Props {}

export default function MyComponent(props: Props) {
  const onSubmit = (e: any) =&amp;gt; {};

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Login &amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={onSubmit}&amp;gt;
        &amp;lt;input type="text" onChange={() =&amp;gt; {}} name="email" /&amp;gt;
        &amp;lt;input type="password" onChange={() =&amp;gt; {}} name="password" /&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To handle input value with two inputs, we will create a custom hooks that handle it, and also handle onSubmit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";

interface Props {}

export default function MyComponent(props: Props) {
  const email = useInputValue(); //** added */
  const password = useInputValue(); //** added */

  const onSubmit = (e: any) =&amp;gt; {
    e.preventDefault();
    const { value: emailValue } = email;
    const { value: passValue } = password;
    if (
      emailValue &amp;amp;&amp;amp;
      emailValue.trim() !== "" &amp;amp;&amp;amp;
      passValue &amp;amp;&amp;amp;
      passValue.trim() !== ""
    ) {

    } else {
      return;
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Login &amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={onSubmit}&amp;gt;
        &amp;lt;input type="text" name="email" {...email} /&amp;gt;
        &amp;lt;input type="password" name="password" {...password} /&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
//** added */
const useInputValue = (defaultValue: string = "") =&amp;gt; {
  const [val, setVal] = useState(defaultValue);
  const handleChange = (e: any) =&amp;gt; setVal(e.target.value);

  return {
    value: val,
    onChange: handleChange
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to access login function we need to have Consumer to access the values login, register&lt;/p&gt;

&lt;p&gt;Consumer hook:&lt;br&gt;
create a file in auth/useAuthentication.ts with content:&lt;/p&gt;

&lt;p&gt;src/auth/useAuthentication.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useContext } from "react";
import { AuthContext, IAuthContext } from "./AuthContext";

export default function useAuthentication(): IAuthContext | undefined {
  return useContext(AuthContext);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will only expose the context to access the values in the Provider.&lt;/p&gt;

&lt;p&gt;Now, we will use it in MyComponent like this:&lt;/p&gt;

&lt;p&gt;src/components/MyComponent.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";
import useAuthentication from "./auth/useAuthentication"; //** added */

interface Props {}

export default function MyComponent(props: Props) {
  const email = useInputValue();
  const password = useInputValue();
  const context = useAuthentication();//** added */

  const onSubmit = (e: any) =&amp;gt; {
    e.preventDefault();
    const { value: emailValue } = email;
    const { value: passValue } = password;
    if (
      emailValue &amp;amp;&amp;amp;
      emailValue.trim() !== "" &amp;amp;&amp;amp;
      passValue &amp;amp;&amp;amp;
      passValue.trim() !== ""
    ) {
      //** added */
      context.login(emailValue, passValue);
    } else {
      return;
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Login &amp;lt;/p&amp;gt;
      &amp;lt;form onSubmit={onSubmit}&amp;gt;
        &amp;lt;input type="text" name="email" {...email} /&amp;gt;
        &amp;lt;input type="password" name="password" {...password} /&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

const useInputValue = (defaultValue: string = "") =&amp;gt; {
  const [val, setVal] = useState(defaultValue);
  const handleChange = (e: any) =&amp;gt; setVal(e.target.value);

  return {
    value: val,
    onChange: handleChange
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And because now you have the context values, we rely on isAuthenticated to show the login form or authenticated page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
      {context.isAuthenticated ? (
        &amp;lt;div&amp;gt;
          &amp;lt;h1&amp;gt;You have been logged on ${email.value}&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
      ) : (
        &amp;lt;div&amp;gt;
          &amp;lt;p&amp;gt;Login &amp;lt;/p&amp;gt;
          &amp;lt;form onSubmit={onSubmit}&amp;gt;
            &amp;lt;input type="text" name="email" {...email} /&amp;gt;
            &amp;lt;input type="password" name="password" {...password} /&amp;gt;
          &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we have covered almost the implementation of auth module but don't we forget something, that's right! the value of isAuthenticated is always false since we didn't implement yet login function.&lt;/p&gt;

&lt;p&gt;Implementation login&lt;br&gt;
For this we can simply create a custom hook that handles it:&lt;/p&gt;

&lt;p&gt;src/auth/AuthProvider.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { ReactElement, useState } from "react";
import { AuthContext } from "./AuthContext";

interface IAuthProviderProps {
  children: ReactElement&amp;lt;any&amp;gt; | ReactElement&amp;lt;any&amp;gt;[];
}
export function AuthProvider({ children }: IAuthProviderProps) {
  const contextValue = useContextChange(); //** added */

  return (
    //** Added */
    &amp;lt;AuthContext.Provider value={contextValue}&amp;gt;{children}&amp;lt;/AuthContext.Provider&amp;gt;
  );
}
//** Added */
const useContextChange = () =&amp;gt; {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const login = (email: string, password: string) =&amp;gt; {
    // some api call.
    fetch("http://localhost/5000", {
      method: "post",
      body: JSON.stringify({
        email,
        password // don't forget to hash the password
      })
    })
      .then(res =&amp;gt; setIsAuthenticated(true))
      .catch(error =&amp;gt; {
        setIsAuthenticated(false);
        throw new Error("[Authenticaion] " + JSON.stringify(error));
      });
  };

  const register = (email: string, password: string) =&amp;gt; {
    // same for register
  };

  return {
    isAuthenticated,
    login,
    register
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that our authentication is done, is it? normally yes. But what if one of our component down in the tree needs to access login, register of &lt;code&gt;isAuthenticated&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in the case we will create another higher order component that can easily wrap any component and access this value:&lt;/p&gt;

&lt;p&gt;src/auth/withAuthentication.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { ComponentType } from "react";
import { AuthContext, IAuthContext } from "./AuthContext";

export default function withAuthentication&amp;lt;T&amp;gt;(
  Component: ComponentType&amp;lt;T &amp;amp; IAuthContext&amp;gt;
) {
  return (props: T) =&amp;gt; (
    &amp;lt;AuthContext.Consumer&amp;gt;
      {context =&amp;gt; &amp;lt;Component {...props} {...context} /&amp;gt;}
    &amp;lt;/AuthContext.Consumer&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: I have noticed that context will not be updated in case which means the component will not render regardless In this case please use useAuthContext hook in to get the last updates to render the component.&lt;/p&gt;

&lt;p&gt;And we can use like this in any component under Provider:&lt;/p&gt;

&lt;p&gt;AnyComponent.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { IAuthContext } from "./auth/AuthContext";
import withAuthentication from "./auth/withAuthentication";

interface Props {}

function AnyComponent(props: Props &amp;amp; IAuthContext) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Yes, you can access this value {props.isAuthenticated}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default withAuthentication(AnyComponent);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's done for this time :)&lt;/p&gt;

&lt;p&gt;Thank you for reading&lt;br&gt;
I hope you learned something here&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Use nuxt-speedkit for Lighthouse performance optimization</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Mon, 20 Sep 2021 13:12:58 +0000</pubDate>
      <link>https://dev.to/joseprest/use-nuxt-speedkit-for-lighthouse-performance-optimization-5fai</link>
      <guid>https://dev.to/joseprest/use-nuxt-speedkit-for-lighthouse-performance-optimization-5fai</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U_5UeVCv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jurdku65aktc3p4kpz98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U_5UeVCv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jurdku65aktc3p4kpz98.png" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick summary
&lt;/h2&gt;

&lt;p&gt;I am going to introduce nuxt-speedkit module.&lt;br&gt;
Nuxt Speedkit takes over the Lighthouse performance optimization of your generated website. All used components and resources are loaded on demand based on the viewport.&lt;/p&gt;

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

&lt;p&gt;In order to achieve a performance score of 100/100, only the resources that are necessary in the current viewport may be loaded. Concepts already exist for the loading of javascript components and images. However, there is not yet a practicable concept for loading fonts dynamically. This module provides a holistic approach to load all necessary resources on demand, including fonts, based on the current viewport.&lt;/p&gt;

&lt;p&gt;This module implements the lazy-hydration concept of Markus Oberlehner and embeds a modified version of nuxt/image.&lt;/p&gt;

&lt;h4&gt;
  
  
  Requirements
&lt;/h4&gt;

&lt;p&gt;NodeJS &amp;gt;= 12.x.x&lt;br&gt;
NuxtJS &amp;gt;= 2.15.0&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;p&gt;dynamic loading of viewport based page resources like fonts (subselectors, media queries), components, pictures&lt;br&gt;
optional loading prevention of resources at low bandwidth or weak hardware&lt;br&gt;
prevents the loading of unnecessary resources (including components) that are outside the current viewport.&lt;br&gt;
optional info layer concept to inform users about a reduced UX when bandwidth or hardware is compromised.&lt;/p&gt;

&lt;h4&gt;
  
  
  Results
&lt;/h4&gt;

&lt;p&gt;delivery of the minimum required resources based on the current viewport&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Your GitHub OAuth token for github.com contains invalid characters on composer install</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Wed, 01 Sep 2021 02:59:25 +0000</pubDate>
      <link>https://dev.to/joseprest/your-github-oauth-token-for-github-com-contains-invalid-characters-on-composer-install-3hp6</link>
      <guid>https://dev.to/joseprest/your-github-oauth-token-for-github-com-contains-invalid-characters-on-composer-install-3hp6</guid>
      <description>&lt;p&gt;If you're receiving this error when trying to composer install.&lt;/p&gt;

&lt;p&gt;Your GitHub OAuth token for github.com contains invalid characters&lt;/p&gt;

&lt;p&gt;The solution is to update Composer to the latest version, which supports the new token format. "Composer 1.10.21 and 2.0.12 (both released April 1st) added support for the new GitHub token format."&lt;/p&gt;

&lt;p&gt;Go to getcomposer.org/download/&lt;br&gt;
Follow the instructions to download the latest phar&lt;br&gt;
As of this writing, the following command will install the latest version of Composer on your machine (i.e., 2.0.13). Note that future Composer updates will break the script as shown here, as the hash check won't pass.&lt;/p&gt;

&lt;p&gt;Edit the composer authentication configuration file ~/.composer/auth.json.&lt;/p&gt;

&lt;p&gt;nano ~/.composer/auth.json&lt;/p&gt;

&lt;p&gt;Then replace the following.&lt;/p&gt;

&lt;p&gt;"github-oauth": {&lt;br&gt;
    "github.com": "ghp_[YOUR-PERSONAL-TOKEN]"&lt;br&gt;
  }&lt;br&gt;
With this (basic auth):&lt;/p&gt;

&lt;p&gt;"http-basic": {&lt;br&gt;
    "github.com": {&lt;br&gt;
      "username": "[YOUR-GITHUB-USERNAME]",&lt;br&gt;
      "password": "ghp_[YOUR-PERSONAL-TOKEN]"&lt;br&gt;
    }&lt;br&gt;
  }&lt;/p&gt;

</description>
      <category>github</category>
      <category>php</category>
    </item>
    <item>
      <title>Advantages of using Firebase for Mobile App Development</title>
      <dc:creator>Jose Godinez  </dc:creator>
      <pubDate>Tue, 03 Aug 2021 02:39:10 +0000</pubDate>
      <link>https://dev.to/joseprest/advantages-of-using-firebase-for-mobile-app-development-2egn</link>
      <guid>https://dev.to/joseprest/advantages-of-using-firebase-for-mobile-app-development-2egn</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J__G3hTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsdizd8dbjugycy2rlkb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J__G3hTD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsdizd8dbjugycy2rlkb.jpg" alt="Alt Text" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Firebase for Mobile App
&lt;/h2&gt;

&lt;p&gt;As mobile apps evolved from being simple entertainment platforms for people to more sophisticated and challenging tools for even enterprises, there was a huge need to improve its backend capabilities. By backend, we meant not just scalable storage, but also high-performance processing engines, flexible integration capabilities and much more.&lt;/p&gt;

&lt;p&gt;Besides, today there is a huge demand for mobile apps to have analytical and artificial intelligence-based capabilities that require even more processing power in the backend. So how can app development companies or businesses that want to build a mobile app to serve customers achieve this level of power in their backend? Well, you do not have to look beyond Firebase for this.&lt;/p&gt;

&lt;p&gt;Backed by Google, Firebase offers a suite of tools required for businesses to build powerful apps without having to worry about management of infrastructure. It is designed to support backend developers at all stages of development and helps in improving the quality of the overall app development exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Firebase is used for mobile app development?
&lt;/h2&gt;

&lt;p&gt;It provides a host of features and modules that an app developer needs, as a service thereby eliminating the need to create these from scratch.&lt;/p&gt;

&lt;p&gt;It includes everything from a scalable database to powerful analytics libraries. Firebase is in no way a replacement for backend development activity, but it is rather a platform to help backend developers and engineers enhance the experience of the app without stressful coding and architectural planning.&lt;/p&gt;

&lt;p&gt;Some interesting features of using firebase:-&lt;/p&gt;

&lt;p&gt;Real-time Data&lt;br&gt;
Security Built-in&lt;br&gt;
Email and Password authentication&lt;br&gt;
Static File Hosting&lt;br&gt;
Storage fostered by Google Cloud &lt;/p&gt;

&lt;p&gt;Now, here are 5 revolutionary advantages brought by Firebase in today’s mobile app development practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Faster time to market
&lt;/h3&gt;

&lt;p&gt;This is one of the key elements that decides how successful a mobile app turns out to be. When consumers get to use your apps or its new features as early as possible, they turn out to be your biggest competitive advantage in extremely sensitive markets.&lt;/p&gt;

&lt;p&gt;For example, imagine that you own a financial management application that consumers use to manage their personal financial expenses. When customers want to use their smartphones increasingly for making payments across their physical and digital shopping destinations, then it is imperative that you roll out the functionality in your app at the earliest or risk losing market share to competitors who do it first.&lt;/p&gt;

&lt;p&gt;A typical back end development exercise for this capability would take months or even years to be production ready. Bring in Firebase, and you could be looking at launching the feature in a matter of weeks thanks to the huge set of processing capabilities and scalable assets it offers. Firebase offers this competitive advantage that you cannot simply ignore.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Reduces development time and effort
&lt;/h3&gt;

&lt;p&gt;For building a backend for your mobile app, there is a requirement for servers, hosting, database, and numerous supporting backend services. You need dedicated development professionals for managing this backend activity as well as another team to work on the front-end mobile app code.&lt;/p&gt;

&lt;p&gt;This leads to increased development efforts, integration time and project management overhead. And above all, dependencies in these two teams will push development timelines further if one team gets held up with some challenges they face.&lt;/p&gt;

&lt;p&gt;Communication and collaboration efforts are also high in such mode of application development which ultimately increases the risk of errors that can lead to severe consequences on the final product.&lt;/p&gt;

&lt;p&gt;Firebase comes preloaded with all such pre-requisites of backend development so that you need not re-invent the wheel for each activity. This is a huge advantage of using firebase for mobile app as a front-end developer who needs a certain backend data type or service can simply integrate his code with the Firebase suite and get the desired input.&lt;/p&gt;

&lt;p&gt;He or his team can manage the end-to-end development for the mobile app thereby reducing overheads and dependency-based challenges to a bare minimum or even eliminate it all together for smaller projects.&lt;/p&gt;

&lt;p&gt;This leads to a drastic reduction of time and effort needed in building mobile apps which is a boon to companies who have smaller development teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Real-Time Database Scalability
&lt;/h3&gt;

&lt;p&gt;Cloud Firestore is the popular database platform within the Firebase suite of offerings. It allows development teams to quickly setup a highly scalable and flexible real time database for their mobile, web and server development activities.&lt;/p&gt;

&lt;p&gt;Elimination of a middle synchronization layer between the application and the backend database results in direct data access through the Firebase SDK.&lt;/p&gt;

&lt;p&gt;It ensures that data is well synchronized within the application environment irrespective of the internet connectivity it has.&lt;/p&gt;

&lt;p&gt;It is a NoSQL database which has been proven to be more effective than relational databases for mobile application-based workloads. It can be used to store large amounts of unstructured or structured data, run powerful processing algorithms and scale on demand to support heavy spikes in data.&lt;/p&gt;

&lt;p&gt;It allows easy storage and management of user-generated content irrespective of the volume of data that is generated. Google’s cloud storage empowers easy scalability for the data storage as well as processing systems to accommodate large volumes seamlessly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Google Analytics Integration
&lt;/h3&gt;

&lt;p&gt;Any kind of personalized experience that you need to provide for your mobile app consumers require insights about their behavior and usage patterns. From a traditional standpoint, you need to either build an analytical engine into your mobile apps backend to process these insights or you may need to integrate powerful 3rd party analytical solutions to get the job done.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gH1i1gCB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mgezy4buh39vw0oev2c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gH1i1gCB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mgezy4buh39vw0oev2c.jpg" alt="Alt Text" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Firebase, you have Google’s own Google Analytics integrated into the core solution and available for you to use to create your own views about customers based on target data behavior. You can easily monitor user behavior, identify journeys across devices and do much more personalization in your mobile apps with the help of in-built Google Analytics.&lt;/p&gt;

&lt;p&gt;It provides you data on where your app scores in terms of user engagement. This allows you to build features and capabilities that customers would want from your app and hence improve brand loyalty and customer satisfaction. It helps in placing the right content for the right audience at the right time to ensure that all your customer needs are well addressed from your mobile app.&lt;/p&gt;

&lt;p&gt;Ultimately, analytics serves as a game-changing feature and highly advantageous in your mobile app’s journey to building a sustainable growth channel for your business powered by user feedback and interests.&lt;/p&gt;

&lt;h3&gt;
  
  
  5) Flexible Cost
&lt;/h3&gt;

&lt;p&gt;Firebase is free to begin with and there are many subscription-based plans for various services within Firebase. Enterprises or startups that want to begin their mobile app journey can use Firebase to explore possibilities in small scales and later expand their capabilities on a pay-as-you-go basis.&lt;/p&gt;

&lt;p&gt;This provides enough financial flexibility for small businesses to compete with established businesses in the race for building innovative mobile based business channels. From e-commerce to mobile payments, there is huge ocean of opportunities that they can explore within their limited financial capabilities and technology constraints.&lt;/p&gt;

&lt;p&gt;The lower starting cost and on-demand pricing allows companies to monetize their mobile channels gradually and maintain low operational costs throughout its lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts:-
&lt;/h2&gt;

&lt;p&gt;Due to these tremendous advantages of using Firebase in Mobile apps, it has revolutionized the way mobile app backends are built today. From cost to effort, there is a huge impact it made in making app backend development more accessible and seamless for businesses of all sizes.&lt;/p&gt;

&lt;p&gt;All that a business needs to create a productive and sustainable roadmap for their mobile app journey is a knowledgeable workforce who can use tools like Firebase to create amazing mobile app experiences for your consumers. We understand the need for you to focus on core business activities and the limit it creates for your resources.&lt;/p&gt;

&lt;p&gt;This is why CitrusBug offers state of the art Firebase development services for mobile app development projects. Our consultants will identify the most profitable growth roadmap for your mobile app, build capabilities with using Firebase for your backend and create solid front-end mobile apps for your customers to use as well. Get in touch with us today to know more.&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>javascript</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
