<?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: Ambuj sahu</title>
    <description>The latest articles on DEV Community by Ambuj sahu (@ambujsahu81).</description>
    <link>https://dev.to/ambujsahu81</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%2F1004731%2F6c776497-5a40-482e-89fd-85064ee81fc7.png</url>
      <title>DEV Community: Ambuj sahu</title>
      <link>https://dev.to/ambujsahu81</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ambujsahu81"/>
    <language>en</language>
    <item>
      <title>Deploy a puppeteer nodejs application on netlify</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Mon, 20 Feb 2023 13:30:24 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/deploy-a-puppeteer-nodejs-application-on-netlify-3b3</link>
      <guid>https://dev.to/ambujsahu81/deploy-a-puppeteer-nodejs-application-on-netlify-3b3</guid>
      <description>&lt;p&gt;In this article, we’ll learn how we can take advantage of packages like &lt;a class="mentioned-user" href="https://dev.to/sparticuz"&gt;@sparticuz&lt;/a&gt;/chromium and Puppeteer-core to create and deploy our puppeteer nodejs application on netlify.&lt;/p&gt;

&lt;p&gt;If you are facing issue to run puppeteer on netlify that could be due to the fact that you are using a library called chrome-aws-lambda. And puppeteer core library which is updated very constantly. So it becomes quite a hassle to use chrome-aws-lambda because of the pace of the puppeteer updates. To resolve this issue we could use &lt;a class="mentioned-user" href="https://dev.to/sparticuz"&gt;@sparticuz&lt;/a&gt;/chromium library as their docs say that this package is not chained to puppeteer versions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let first create a simple node application.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;application&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;application&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Now we can also install netlify libraries which will help us to deploy our nodejs application.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;netlify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cli&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Now create a dist folder with empty &lt;code&gt;index.html&lt;/code&gt; file in it. This is the required netlify configuration.&lt;/li&gt;
&lt;li&gt;Now create a dist folder with empty &lt;code&gt;index.html&lt;/code&gt; file in it. This is required for netlify configuration.&lt;/li&gt;
&lt;li&gt;Now create a file name &lt;code&gt;netlify.toml&lt;/code&gt; file and copy the following code in it. This will help netlify recognize where the functions are stored.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Now create the function directory where we will keep our node puppeteer code. In this directory create a file name &lt;code&gt;api.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now lets install puppeteer dependencies to start using puppeteer code in our application
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;19&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;6.0&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;serverless&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;sparticuz&lt;/span&gt;&lt;span class="sr"&gt;/chromium@11&lt;/span&gt;&lt;span class="err"&gt;0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Note: In order to figure out what version of &lt;a class="mentioned-user" href="https://dev.to/sparticuz"&gt;@sparticuz&lt;/a&gt;/chromium you will need, please visit &lt;a href="https://pptr.dev/chromium-support" rel="noopener noreferrer"&gt;Puppeteer's Chromium Support page&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Finally copy the following code in the &lt;code&gt;api.js&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now finally run following netlify commands to deploy the application and you need to select few option where you could either link this deployment to an existing site or to a new site. 
If you are doing it for the first time then select a new site and give it a new name.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;netlify&lt;/span&gt; &lt;span class="nx"&gt;deploy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally you could check the deployment links and don't forget to append &lt;code&gt;/.netlify/functions/api&lt;/code&gt; at the end of the deployment url to be able to access the node application.&lt;/p&gt;

&lt;p&gt;You can also refer the sample code for same &lt;a href="https://github.com/ambujsahu81/backend-framework-detector" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Create a simple GitHub Actions Workflow</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Sat, 04 Feb 2023 09:10:56 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/create-a-simple-github-actions-workflow-347n</link>
      <guid>https://dev.to/ambujsahu81/create-a-simple-github-actions-workflow-347n</guid>
      <description>&lt;p&gt;If you are trying to build any software project you definitely need an workflows to build and test your project. GitHub Actions workflow can help you by automating, customizing and executing the workflow itself.&lt;/p&gt;

&lt;p&gt;In this post, we're going to create a simple GitHub action workflow that will check the build status and test the code every time someone pushes the code or creates the pull request.&lt;/p&gt;

&lt;p&gt;Let try to understand first the concepts related to GitHub action workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions Workflow Building Blocks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Workflow:&lt;/strong&gt; The workflow define the specific automation procedures, instructions and actions which run after an event is triggered or scheduled. The workflow is written in the &lt;code&gt;.yml&lt;/code&gt;(YAML) file which is created in the project repository itself.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Workflow Triggers:&lt;/strong&gt; Triggers are the events that will decide when the GitHub workflow  will run. These triggers can be of four types. These are :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual trigger.&lt;/li&gt;
&lt;li&gt;A predefined schedule.&lt;/li&gt;
&lt;li&gt;Events happening in the workflow’s GitHub repository.&lt;/li&gt;
&lt;li&gt;Events occurring outside of GitHub, which trigger a repository dispatch event in GitHub.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runners:&lt;/strong&gt; The workflow requires an environment where it can be executed. For example if we build or test our project we use our own environment usually it is a dedicated system that we are using. Just like our dedicated system &lt;strong&gt;Runners&lt;/strong&gt; are servers where the workflow will be executed. Runner are always listening for events to trigger the workflow.&lt;/li&gt;
&lt;/ul&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jobs:&lt;/strong&gt; Jobs are pretty much self explanatory they contain a series of steps that runs within the runners environment. Every workflow needs at least one job. By default the jobs under the same workflow runs in parallel.&lt;/li&gt;
&lt;/ul&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actions:&lt;/strong&gt; Actions are the smallest unit. The actions of a job are specified with the &lt;code&gt;steps&lt;/code&gt; syntax. Each step can have a name, own environment variables, and commands to run.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Okay now as we know enough about the basic terminologies of workflow, we can get back to create simple GitHub action workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions Workflow Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; In your project repository create a dedicated directory to store workflow files. The directory must be named as -&lt;code&gt;.github/workflows&lt;/code&gt; This directory is where GitHub will look for the workflow files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2)&lt;/strong&gt; Create a &lt;code&gt;.yml&lt;/code&gt; file in &lt;code&gt;github/workflows&lt;/code&gt; directory. You can name this file anything you like but for now, we are naming it as &lt;code&gt;main.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3)&lt;/strong&gt; Now add a name of the workflow for example use the following line at the beginning of the &lt;code&gt;main.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;4)&lt;/strong&gt; Add &lt;code&gt;on&lt;/code&gt; attribute which will tell GitHub when to run the the  workflow. In our case we want to run the workflow when code is pushed or there is a pull request. use the following lines on your &lt;code&gt;main.yml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;5)&lt;/strong&gt; Now we want to create two jobs one for checking the build and another for testing the code. Let start with &lt;code&gt;check-build&lt;/code&gt; jobs that will contains the following steps and run-ons attribute:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;check-build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;14'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;run-ons attribute as described earlier will decide which environment the build will be created. Now if you focus on the steps attribute has two run attribute to execute the commands  &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm run build&lt;/code&gt; which is exactly how you would do it in your local system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6)&lt;/strong&gt; Lets move on the testing the code that should check if the code contains any lint issues, formatting issues or check if any of the test are failing. For this we will create a &lt;code&gt;check-code&lt;/code&gt; job that will contain the following steps:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;check-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;14'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prettier on Node ${{ matrix.node }}&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run prettier:check&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run eslint --ext .ts ./src&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; The above code assumes that you have setup prettier and eslint in your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7)&lt;/strong&gt; Now the final workflow &lt;code&gt;main.yml&lt;/code&gt; file should match the following gist:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8)&lt;/strong&gt; Now finally you can commit your code and push it to the GitHub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9)&lt;/strong&gt; You can further check the build status in your code repository Action tab.&lt;/p&gt;

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

&lt;p&gt;Thanks for reading this Create a simple GitHub Actions Workflow blog. I hope it has been a helpful read.&lt;/p&gt;

</description>
      <category>devto</category>
      <category>announcement</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Focus management in react</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Mon, 30 Jan 2023 18:43:32 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/focus-management-in-react-1npd</link>
      <guid>https://dev.to/ambujsahu81/focus-management-in-react-1npd</guid>
      <description>&lt;p&gt;The design and creation of websites should be such that it can be used by everyone. It should also increase usability and reduce confusion for both keyboard-only and screen reader users.&lt;/p&gt;

&lt;p&gt;when website are created using react, the content of website are updated very frequently which can lead to issues such as that the focus element is no longer in the dom. And keyboard focus is lost or set to an unexpected element. This means the keyboard-only user has to navigate through the entire page again to get back to where they were. To solve such issues we need to programmatically nudge the keyboard focus in the right direction. Doing this will ensure that the web application can be fully operated with the keyboard only.&lt;/p&gt;

&lt;h3&gt;
  
  
  WCAG
&lt;/h3&gt;

&lt;p&gt;Web accessibility (also referred to as a11y) requires that we create website by following WCAG ( Web Content Accessibility Guidelines ). The WCAG checklists includes lot of things such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every HTML form control, such as  and , needs to be labeled accessibly.&lt;/li&gt;
&lt;li&gt;Error situations need to be understood by all users.&lt;/li&gt;
&lt;li&gt;Ensure that your web application can be fully operated with the keyboard only which is exactly same as focus management. &lt;/li&gt;
&lt;li&gt;Ensure that all functionality exposed through a mouse or pointer event can also be accessed using the keyboard alone.&lt;/li&gt;
&lt;li&gt;Provide a mechanism to allow users to skip past navigation sections in your application as this assists and speeds up keyboard navigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article we will try to discuss how we can manage focus in our react app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focus Management in React
&lt;/h3&gt;

&lt;p&gt;Keyboard focus refers to the current element in the DOM that is selected to accept input from the keyboard. We want to set focus to a particular element in react component, when after the deletion of particular element or perhaps after form submission or after component first mounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Targeting our elements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To set focus to our target element in React, we need to use  React's &lt;a href="https://reactjs.org/docs/hooks-reference.html#useref" rel="noopener noreferrer"&gt;useRef&lt;/a&gt; hook.&lt;/p&gt;

&lt;p&gt;1) Add a import statement in your react component. so that it includes &lt;code&gt;useRef&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) create a new constants in the component that has the target element. Something like below :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetELementRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ref has a default value of null because it will not have value until we attach the ref to target element to focus.&lt;/p&gt;

&lt;p&gt;3) we'll add an attribute of ref to target element, and set its values to the ref objects that we added above. Let suppose you want to focus input element when component first mounts. Than the input component should be updated like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CustomTextInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetELementRef&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;targetELementRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Note:&lt;/code&gt; Some html elements are not usually focusable like header e.g. &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; . But we can make any element programmatically focusable by adding the attribute &lt;code&gt;tabindex="-1"&lt;/code&gt; to it.&lt;/p&gt;

&lt;p&gt;4) setting focus to our target input element using &lt;code&gt;useEffect()&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useEffect()&lt;/code&gt; hooks runs after React renders a given component. This make sense in our situation because we don't want browser to focus the element if the component itself is not yet rendered.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the import statement of the component again to add &lt;code&gt;useEffect&lt;/code&gt;. e.g.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now add the following &lt;code&gt;useEffect&lt;/code&gt; hook to the component:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;targetELementRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second value in the &lt;code&gt;useEffect&lt;/code&gt; is an empty array. Because we want to focus input element when the component first mount, we have used an empty array. It simply tells React that your effect doesn't depend on any values from props or state, so it never needs to re-run.&lt;/p&gt;

&lt;p&gt;But if we want to focus when after the deletion of particular element or perhaps after form submission. We can pass the Some value in the props and update the useEffect as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;targetELementRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;someValue&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so the final code should updated like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CustomTextInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetELementRef&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependedValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;targetELementRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;someValue&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;targetELementRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At last if you are stuck with a problem that there is no target element to focus, it can happen if you delete an list item and there are no more list items to focus. In that case you can focus the list heading by making list heading focusable using `tabindex="-1" on the list heading or you can move the focus to next actionable item. &lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility" rel="noopener noreferrer"&gt;"Accessibility in React" on mdn&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cryptocurrency</category>
      <category>crypto</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Where to store data in chrome extension ?</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Wed, 25 Jan 2023 10:10:40 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/where-to-store-data-in-chrome-extension--1be6</link>
      <guid>https://dev.to/ambujsahu81/where-to-store-data-in-chrome-extension--1be6</guid>
      <description>&lt;p&gt;In this post, we're going to use &lt;code&gt;chrome.storage&lt;/code&gt; API to store, retrieve, and track changes to user data in the chrome extension. &lt;/p&gt;

&lt;p&gt;If you are building your first chrome extension than you might stumble across a problem of storing user data specific to each site. Using &lt;code&gt;chrome.storage&lt;/code&gt; API is the easiest way to solve the problem and it can also help you to establish a indirect communication channel between the extensions and the content scripts.&lt;/p&gt;

&lt;p&gt;So let's get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. To use the storage API, declare the "storage" permission in the extension manifest. For example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My extension"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"storage"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Create a file &lt;code&gt;storage.ts&lt;/code&gt; which will act as a storage utility file to keep all the methods you need to work with &lt;code&gt;chrome.storage&lt;/code&gt; Api. For example:&lt;/strong&gt; &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The setter and getter will help you to store and retrieve user data from chrome extension local storage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Now you can import &lt;code&gt;localStorage&lt;/code&gt; from storage.ts file in your extension or in your content script. For example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../shared/storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// To get the data from local storage use follow&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// to save the data simply use&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; Think of adding to storage as being like putting something in a pipe. The pipe may have material in it already, and it may even be filled. Always assume a delay between when you add to storage and when it is actually recorded&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. In your content script you can listen to the changes done to stored data by adding the following&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateDom&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The listen method will need a callback function which will be called every time any changes is done to stored user data. Hence it act as communication channel between content script and the extension. you can now easily update the &lt;code&gt;dom&lt;/code&gt; or trigger some content script work by updating the local storage in your extension.&lt;/p&gt;

&lt;p&gt;You can find the complete code sample &lt;a href="https://github.com/ambujsahu81/Website-Customizer-Plus"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/extensions/reference/storage/"&gt;chrome.storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>chromeextension</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Implementing Singleton in TypeScript</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Tue, 17 Jan 2023 19:57:56 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/implementing-singleton-in-typescript-2fp4</link>
      <guid>https://dev.to/ambujsahu81/implementing-singleton-in-typescript-2fp4</guid>
      <description>&lt;h3&gt;
  
  
  What is the Singleton design pattern?
&lt;/h3&gt;

&lt;p&gt;Implementing the singleton design pattern ensure that there is only one instance of a class. It essentially controls of when and how that the single instance of the class is created and provides   global access point to that single instance. It also restrict the developers from creating new instance of the class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantage of using singleton design pattern ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To keep resource utilization under control that is some objects &lt;br&gt;
consumes too much time or resources to be created. So by making &lt;br&gt;
the class singleton restricts the option to have multiple objects of the same class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory overhead is reduced as the singleton pattern has only one instance in memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To keep a single channel of communication with an outside resource open all the time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some well known examples of Singleton design pattern are logging, caching, and database connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's try to implement singleton design pattern in typescript
&lt;/h3&gt;

&lt;p&gt;we need to make sure that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;there is no option to create multiple instance of the class. To achieve this we can make our class constructor specifier as &lt;code&gt;private&lt;/code&gt;. These way the ability to create new instance using &lt;code&gt;new&lt;/code&gt; keyword will only be possible within the class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;function and method can be called without the need to create instance of the object. These we can achieve by making method and function static. A static method  don’t need an instance of the class to be used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive into code&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we have a &lt;code&gt;TaskListTemplates&lt;/code&gt; class which helps to render the task list in the dom. And the constructor is private. So that if you try to instantiate this class using &lt;code&gt;new&lt;/code&gt; keyword from outside, then TypeScript compiler will prompt the following error message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Constructor of class 'TaskListTemplates' is private and only accessible within the class TaskListTemplates.ts(2673)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we can use the &lt;code&gt;TaskListTemplates&lt;/code&gt; class as follow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./templates/TaskListTemplates&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;taskList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;taskList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By having TaskListTemplates class as singleton, we made sure that there only one task list instance manipulating the dom (instead of accidentally instantiating several at once, and having duplicate task list showing in the dom).&lt;/p&gt;

&lt;p&gt;we can further verify its functionality&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;taskListOne&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;taskListTwo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TaskListTemplates&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskListOne&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;taskListTwo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the complete code sample &lt;a href="https://github.com/ambujsahu81/Typescript_practice/tree/main/src/templates" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>The never type in typescript</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Sat, 14 Jan 2023 16:09:42 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/the-never-type-in-typescript-3li9</link>
      <guid>https://dev.to/ambujsahu81/the-never-type-in-typescript-3li9</guid>
      <description>&lt;h3&gt;
  
  
  The never type
&lt;/h3&gt;

&lt;p&gt;The never type is used when you are sure that something is never going to happen. It simply represents a state which shouldn’t exist.&lt;/p&gt;

&lt;p&gt;It might be return type of function that never returns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;throwError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, both reportError and loop type function either throw errors or return infinite loop that will be analyzed by TypeScript control flow as functions with unreachable endpoints, thus specifying their return type as never.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; When a function is throw-only, it gets the type never if it's an expression, and void if it's a declaration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Should never get here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here foo is () =&amp;gt; void. Read more about it in &lt;a href="https://stackoverflow.com/questions/40251524/typescript-never-type-inference" rel="noopener noreferrer"&gt;StackOverFlow answer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exhaustiveness checking
&lt;/h3&gt;

&lt;p&gt;you can use never type for narrowing and turning up to do exhaustive checking in a switch statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Circle&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getArea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sideLength&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_exhaustiveCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_exhaustiveCheck&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here getArea function which tries to assign the shape to never will raise the issue that every possible case has not been handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assignability in TypeScript
&lt;/h3&gt;

&lt;p&gt;The never type is assignable to every type; however, no type is assignable to never (except never itself).It can be understood as "the smallest type".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="c1"&gt;// ✨ `never` is assignable to all types.&lt;/span&gt;
  &lt;span class="c1"&gt;// It is a subtype of all types.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getNever&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numberValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;stringValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;objectValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;unknownValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;anyValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;neverValue1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;neverValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ✅&lt;/span&gt;


  &lt;span class="nx"&gt;neverValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌&lt;/span&gt;
  &lt;span class="nx"&gt;neverValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌&lt;/span&gt;
  &lt;span class="nx"&gt;neverValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// ❌&lt;/span&gt;
  &lt;span class="nx"&gt;neverValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;anyValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Void Vs Never
&lt;/h3&gt;

&lt;p&gt;The never type looks very similar to void. But the void type can have undefined or null as a value where as never cannot have any value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error: Type 'null' is not assignable to type 'never'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Intersection and Union with never type
&lt;/h3&gt;

&lt;p&gt;In intersection types, it absorbs all types, and in union types all types absorb it. This is because never is a subtype of all types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;anyTypeUnion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// any&lt;/span&gt;
 &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;anyTypeIntersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// never&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;-  &lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html" rel="noopener noreferrer"&gt;Everyday Types&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;- &lt;a href="https://stackoverflow.com/questions/42291811/use-of-never-keyword-in-typescript" rel="noopener noreferrer"&gt;Stackoverflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;- &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#the-never-type" rel="noopener noreferrer"&gt;TypeScript Release notes&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>hiring</category>
      <category>career</category>
      <category>community</category>
    </item>
    <item>
      <title>File Tree Structure using CSS</title>
      <dc:creator>Ambuj sahu</dc:creator>
      <pubDate>Wed, 11 Jan 2023 14:10:58 +0000</pubDate>
      <link>https://dev.to/ambujsahu81/file-tree-structure-using-css-2h64</link>
      <guid>https://dev.to/ambujsahu81/file-tree-structure-using-css-2h64</guid>
      <description>&lt;p&gt;&lt;strong&gt;File tree structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is very simple but amazing file structure design in Pure CSS that you can apply to an unordered list, just follow the below steps : -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a simple html file&lt;/li&gt;
&lt;li&gt;use nested HTML Unordered Lists
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;root
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;folder one
      &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;file_one.txt&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;file_two.txt&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;folder two
      &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;file_one.txt&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;file_two.txt&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add a span inside every li element
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;file_one.txt&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;you can add some folder and files icon or svg in the li element to make the file tree structure look more real &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;folder icon &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9g22ubgk3pva8hcetwe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9g22ubgk3pva8hcetwe.jpg" alt="folder icon" width="171" height="35"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fa-regular fa-folder-open"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;root&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;...rest&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now finally add some css magic to complete the file tree structure.

&lt;ul&gt;
&lt;li&gt;create L shape line by adding following css to the empty span.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;    &lt;span class="nt"&gt;border-bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;solid&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;border-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;solid&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;inline-block&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;margin-bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;margin-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;final output preview&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqmm3d7wqubd9vzcgkyf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqmm3d7wqubd9vzcgkyf.jpg" alt="final preview" width="466" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you can find live example &lt;a href="https://ambujsahu81.github.io/Notes/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Also checkout the code pointer for the same &lt;a href="https://github.com/ambujsahu81/Notes/blob/bd519982ed638d2aabff90b1c71f501c89aa0603/docs/main.js#L187" rel="noopener noreferrer"&gt;code sample&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>career</category>
    </item>
  </channel>
</rss>
