journey through web development

Tag: tutorials

Create a simple toggle switch in React

Dark themes have become really popular in the recent years, and a lot of websites have given their users the ability to choose between light and dark mode. This personalisation also increases accessibility, as some people struggle to read black letters on white background, and prefer to switch to light letters on a dark background.
Toggle switch is, in my opinion, the best way to incorporate light/dark mode feature. Today I’m gonna show you how to create a simple, yet effective toggle switch.

The first thing we need is a design of your toggle.
I’ve made mine using Figma. The sun and moon icons are from Iconify plugin, and gradients were made with uiGradients plugin. When you’re happy with your design, save your file and export the icons (if your have them of course, as they are not mandatory).

Now open the editor of your choice, I’m using Visual Studio Code on my personal computer. Open the folder in which you would like your project directory be. Then, open the terminal and type:

npx create-react-app toggle 
# toggle is the name of your project

when your react app is created, go to your project’s directory using:

cd toggle 
#again, toggle is the name of your project

the last step before we can start our application is starting the server:

npm start

Your project should now open up in your browser, and you should see generic React app page.

We will be using styled-components, so we need to install it in our project. Open a new terminal window and type:

npm install-s styled-components

Ok, so let’s have a look at our project’s folders. We have node_modules, public, src, .gitignore, package-lock.json, package.json and README.md. In the src folder, if your have any icons, create a folder for your assets and them here. Create a folder callled components, in which add a new file: toggle.js

Now, open App.js file and delete everything from inside the div className=”App”. This was what you saw in the generic React page in your browser. We won’t be needing in. Ok, now we need to import our component. At the top of the file, type:

import ToggleComponent from './components/toggle';

Now we can add this component inside the div, and this is how our App.js file should look like now:

import './App.css';
import ToggleComponent from './components/toggle';
function App() {
  return (
    <div className="App">
        <ToggleComponent />
    </div>
  );
}
export default App;

Save and then open toggle.js file. At the top of the document, import React, useState, useEffect and also styled (our styled-components) and keyframes for animations.

import React, { useState , useEffect} from "react";
import styled, { keyframes } from 'styled-components';

To help us out later on, let’s create few const’s that will keep some of our values:

const time = '0.1s';
const lightBackground = 'linear-gradient(90deg, #EAC29C 0%, #EDE8CF 100%)';
const darkBackground = 'linear-gradient(90deg, #46517F 0%, #8DA5B4 100%)';
const setAnimation = (from, to) => keyframes({from: from, to: to});

Components can have one default function, and many regular ones. Let’s create our default one, which will be exported so we can use it in App.js

function ToggleComponent() {
 
    return (
        <OuterWrapper>
            <StyledWrapper>
                <Header>
                    Toggle Switch
                </Header>
                <Toggle />
            </StyledWrapper>
        </OuterWrapper>
      
)}
export default ToggleComponent;

Inside the return braces we will code our component, just like you would code in HTML, but with a twist of styled components.
Styled components let you write CSS inside the .js file, so you don’t have to go back and forth between files and those styled will only apply for that specific component.

To create a styled component, above the function type:

const OuterWrapper = styled.div`
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: ${lightBackground};
    animation: ${time} ${({ showBackground }) => showBackground && setAnimation({ background: 
    lightBackground }, { background: darkBackground })} linear;
    animation-fill-mode: forwards;
`;

this is my styled div named OuterWrapper. You can see, inside is just a regular CSS values. Ok let’s create const’s for all divs, h1 and span. All the changes will be showing in your browser straight away, so don’t be afraid to use Inspect tab and play around with different values!

const OuterWrapper = styled.div`
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: ${lightBackground};
    animation: ${time} ${({ showBackground }) => showBackground && setAnimation({ background: 
    lightBackground }, { background: darkBackground })} linear;
    animation-fill-mode: forwards;
`;
const StyledWrapper = styled.div`
    display: flex;
    justify-content: center;
    flex-direction: column;
    height: 50vh;
    margin:0 auto;
    z-index: 10000;
`;
const Header = styled.h1`
    color: #333333;
    animation: ${time} ${({ showLightfont }) => showLightfont && setAnimation({ color: 
    '#333333' }, { color: '#ffffff' })} linear;
    animation-fill-mode: forwards;
    position: relative;
    font-size: 40px;
    font-family: 'Raleway Dots', cursive;
    display: flex;
    align-items: center;
    margin-bottom:40px;
`;
const StyledToggle = styled.div`
   border-radius: 50px;
   background:  linear-gradient(90deg, #FFA751 0%, #FFE259 100%);
   animation: ${time}  ${({dark}) => dark && setAnimation({background: lightBackground}, 
   {background: darkBackground})} linear;
   animation-fill-mode: forwards;
   height: 32px;
   width: 58px;
   display:flex;
   position: relative;
   align-self: center;
   z-index:100;
   box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 0px 2px rgba(0, 0, 0, 0.06), 0px 0px 1px 
   rgba(0, 0, 0, 0.04);
`;
const StyledSwitch = styled.span`
   background: #ffffff url('./assets/smiley-sun.svg') no-repeat center;
   z-index: 101;
   width:28px;
   height: 26px;
   border-radius: 50px;
   display:flex;
   justify-content:center;
   align-self: center;
   margin-left: 3px;
   margin-top:0.5px;
   z-index: 10000;
   animation: ${time}  ${({dark}) => dark && setAnimation({marginLeft: '3px', background: 
   '#ffffff url(\'./assets/smiley-sun.svg\') no-repeat center'}, {marginLeft: '26px', 
   background: '#ffffff url(\'./assets/smiley-moon.svg\') no-repeat center'})} linear;
   cursor: pointer;
   animation-fi

Ok let’s create a Toggle component function! Having it separate from the default function, we will be able to use our toggle anywhere else in the app, and have multiple different toggles. DRY coding! (don’t repeat yourself)

const Toggle = (props) => {
    const [dark, setDark] = useState(false);
    const {onDark, onNotDark} = props;
    useEffect(() => {
        if (!dark) {
            onNotDark();
            return;
        }
        onDark();
    }, [dark])
    const handleClick = () => {
        setDark(!dark)
    }; 
    return (
        <StyledToggle dark={dark}>
            <StyledSwitch dark={dark} onClick={handleClick} />
        </StyledToggle>
    )};

In our toggle, we are using states for light and dark setting. We have also added an onClick event to the StyledSwitch span.

We need to remember that any change of state can only go down from a parent to the child element. A child component cannot be responsible for those (because kids aren’t responsible, right? 😂) To make our toggle work, we need to give a parent (our default ToggleComponent) some responsibility.

function ToggleComponent() {
    const [showBackground, setShowBackground] = useState(false);
    const [showLightfont, setShowLightfont] = useState(false);
    const handleNotDark = () => setShowBackground(false) & setShowLightfont(false);
    const handleDark = () => setShowBackground(true) & setShowLightfont(true);
    
    return (
        <OuterWrapper showBackground={showBackground}>
            <StyledWrapper>
                <Header showLightfont= {showLightfont}>
                    Toggle Switch
                </Header>
                        <Toggle onNotDark= {handleNotDark} onDark= {handleDark} />
            </StyledWrapper>
        </OuterWrapper>
);
}

This is how our parent looks like now.

import React, { useState , useEffect} from "react";
import styled, { keyframes } from 'styled-components';
const time = '0.1s';
const lightBackground = 'linear-gradient(90deg, #EAC29C 0%, #EDE8CF 100%)';
const darkBackground = 'linear-gradient(90deg, #46517F 0%, #8DA5B4 100%)';
const setAnimation = (from, to) => keyframes({from: from, to: to});
const OuterWrapper = styled.div`
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: ${lightBackground};
    animation: ${time} ${({ showBackground }) => showBackground && setAnimation({ background: 
    lightBackground }, { background: darkBackground })} linear;
    animation-fill-mode: forwards;
`;
const StyledWrapper = styled.div`
    display: flex;
    justify-content: center;
    flex-direction: column;
    height: 50vh;
    margin:0 auto;
    z-index: 10000;
`;
const Header = styled.h1`
    color: #333333;
    animation: ${time} ${({ showLightfont }) => showLightfont && setAnimation({ color: 
    '#333333' }, { color: '#ffffff' })} linear;
    animation-fill-mode: forwards;
    position: relative;
    font-size: 40px;
    font-family: 'Raleway Dots', cursive;
    display: flex;
    align-items: center;
    margin-bottom:40px;
`;
const StyledToggle = styled.div`
   border-radius: 50px;
   background:  linear-gradient(90deg, #FFA751 0%, #FFE259 100%);
   animation: ${time}  ${({dark}) => dark && setAnimation({background: lightBackground}, 
   {background: darkBackground})} linear;
   animation-fill-mode: forwards;
   height: 32px;
   width: 58px;
   display:flex;
   position: relative;
   align-self: center;
   z-index:100;
   box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 0px 2px rgba(0, 0, 0, 0.06), 0px 0px 1px 
   rgba(0, 0, 0, 0.04);
`;
const StyledSwitch = styled.span`
   background: #ffffff url('./assets/smiley-sun.svg') no-repeat center;
   z-index: 101;
   width:28px;
   height: 26px;
   border-radius: 50px;
   display:flex;
   justify-content:center;
   align-self: center;
   margin-left: 3px;
   margin-top:0.5px;
   z-index: 10000;
   animation: ${time}  ${({dark}) => dark && setAnimation({marginLeft: '3px', background: 
   '#ffffff url(\'./assets/smiley-sun.svg\') no-repeat center'}, {marginLeft: '26px', 
   background: '#ffffff url(\'./assets/smiley-moon.svg\') no-repeat center'})} linear;
   cursor: pointer;
   animation-fill-mode: forwards;
`;
const Toggle = (props) => {
    const [dark, setDark] = useState(false);
    const {onDark, onNotDark} = props;
    useEffect(() => {
        if (!dark) {
            onNotDark();
            return;
        }
        onDark();
    }, [dark])
    const handleClick = () => {
        setDark(!dark)
    }; 
    return (<StyledToggle dark={dark}>
        <StyledSwitch dark={dark} onClick={handleClick}></StyledSwitch>
    </StyledToggle>
    )};
function ToggleComponent() {
    const [showBackground, setShowBackground] = useState(false);
    const [showLightfont, setShowLightfont] = useState(false);
    const handleNotDark = () => setShowBackground(false) & setShowLightfont(false);
    const handleDark = () => setShowBackground(true) & setShowLightfont(true);
    
    return (
        <OuterWrapper showBackground={showBackground}>
            <StyledWrapper>
                <Header showLightfont= {showLightfont}>
                    Toggle Switch
                </Header>
                        <Toggle onNotDark= {handleNotDark} onDark= {handleDark} />
            </StyledWrapper>
        </OuterWrapper>
);
}
export default ToggleComponent;

And that is our complete component file. If your would like a nice fonts, either import the font into your project, or add a link into the head of index.html file.

OK time to deploy your project and publish it! Github pages will be the best option for our needs today.
Commit your work, then go into your github account and create a new empty repository. Follow the steps to add existing repository:

git remote add origin https://github.com/your-username/name-of-your-project.git
git branch -M main
git push -u origin main

Now we need to install gh-pages package. In your terminal, type:

npm install gh-pages --save-dev

In package.json file, add:

"homepage" : "http://katwlodarczyk.github.io/toggle-switch-react" 
#add this after name of the project. this is your github pages url

and lastly, we need to add some new scripts:

"predeploy": "npm run build",
"deploy": "gh-pages -d build"

Ok. let’s deploy! In the terminal, type:

npm run deploy

Wait and…. viola!

You can see my finished project here:

https://katwlodarczyk.github.io/toggle-switch-react/

GitHub repository to see the whole code:

https://github.com/katwlodarczyk/toggle-switch-react

Toggle switch project on Behance:

https://www.behance.net/gallery/108743485/Toggle-switch


If you’ve done your very own awesome toggle, share the link with me!

Liked this post? Share:

How to create a digital portrait in adobe illustrator

A few days ago, while I needed a little break from my database assignment, I created this digital portrait of my daughter, Hannah.

Everyone seemed to really like it, so I decided to share my knowledge and create a tutorial on how to do those cool portraits using any photograph.

All you need is Adobe Illustrator and a photograph! No skills required and it’s really easy to do!

Watch a video tutorial or follow my written instructions below!

How to create a digital portrait using Adobe Illustrator:

  1. Choose a photograph you would like to use for this project. It can be literally anything you want! I chose this cute photograph of Hannah-ballerina:
  2. Open Adobe Illustrator, click a New File and choose the size of your canvas. For this project I chose A4, but you can choose a different size.
  3. Click the Window tab and then select Layers. This step is really important as layers are crucial!
  4. Click File tab and Place, to place a chosen photograph onto Layer 1. Next, place the image on the canvas.
  5. Lock the Layer 1, add a new layer, zoom in onto the face (or any other part you want to start with) so you can see the area better, and using the Pen tool, start outlining the shape of the face.

    Remember to change the size and style of the brush! I like to outline the skin with the smallest brush size (0.25) and hair and clothes with a slightly bigger one (0.5) Play with different brush styles and choose the one you like the most.

  6.  
  7. Name a layer accordingly, and lock the layer using the lock icon in the layers tab.
  8. Add another layer and outline the left ear. Name a layer and then click the down arrow to open this layer, and lock the one inside (not the whole layer)
  9. Outline the shadows inside the ear outline. Lock the whole layer and outline the other areas following the same rules.
    One area= one layer. Lock layers when you finish them.
    For this photograph, I have layers for: face, left ear, right ear, hair, neck, top of the dress, tutu skirt, left hand, right hand, and legs.
  10. When you finish outlining, you can unclick the eye icon next to the Layer 1 (with the original photograph) to see how you’re doing.
  11. You’re halfway there!
  12. Ok now click the eye icon on Layer 1 again to bring back the original photo, if you would like to use color from it. If you choose to have custom colors, this step is not necessary.
  13. Unlock the first layer (in my case, it’s a face layer) and using the Eyedropper tool, select the color of your liking from the original image. Then select the outline of the face layer and click on the color swatch you just chose.
  14. Lock the layer again and fill in other skin areas, like ears(just the main outline), neck and hands.
  15. Unlock the ears layer, and select the inside outlines, color them with the same color and then double-click on the color swatch (big color square in the left side menu) and select a darker shade. Fill with the same color other inside ear’s outlines.
  16. You may want to take the stroke of the outlines out if you wish (in the right-hand side menu).
  17. Color other layers the same way.
  18. Now create a new layer for the background. Place it on the bottom of the layers (so it’s in the back of your portrait) Using the rectangle tool, select the area of your canvas and fill with the color of your liking.
  19. Add another layer, place it on top of the background layer, and using the Curvature Tool, draw a “blob” around your portrait. It doesn’t have to be perfect so play with it 🙂 Again, fill with any color you like.
  20. Add a new layer and using the Text tool, add a text. I like to separate lines of text to have more control over the alignment of the lines. Choose your font and the size of the text.
  21. Voila! You have just created a digital portrait!

I would love to see your creations, so please tag me on Twitter @kat_wlodarczyk and use the #katstutorials
so I can see them! You can also comment or email me!
I hope you liked this tutorial!
✌️

Liked this post? Share:

© 2021 KAT CODES

Theme by Anders NorenUp ↑