Skip to content

This is my solution to the REST Countries API with color theme switcher challenge on Frontend Mentor.

Notifications You must be signed in to change notification settings

cholis04/rest-countries-api

Repository files navigation

Frontend Mentor - REST Countries API with color theme switcher solution

This is a solution to the REST Countries API with color theme switcher challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Users should be able to:

  • See all countries from the API on the homepage
  • Search for a country using an input field
  • Filter countries by region
  • Click on a country to see more detailed information on a separate page
  • Click through to the border countries on the detail page
  • Toggle the color scheme between light and dark mode (optional)

Screenshot

Homepage - (Light Mode) Homepage Light Mode

Detail Country Page - (Dark Mode) Detail Country Page Dark Mode

Link

My process

Built with

What I learned

This project is very interesting. I learned new things that can be applied to complete this project well. Here are the details:

Input Type Search

Usually I will use input Tag with text type. But HTML has another type which is search. In this type, some web browsers will display an empty button (x) when we type something in it.

Input Type Search

<input
  type="search"
  id="country"
  name="country"
  aria-label="Name of Country"
  placeholder="Search for country..."
/>

Object Fit Scale Down

Object fit Scale Down

Displaying an Image in a container that has a fixed size is quite a tricky thing. Given also we need to adjust to the width of the screen to be responsive.

However, some images have different sizes, if you use object-fit:cover;, then there are some parts of the flag image that are not visible.

Therefore, I implemented object-fit:scale-down. thus displaying the image flag in full without being cropped and the height of the image container will be the same size.

.flag-image {
  object-fit: scale-down;
  object-position: center;
}

Prefers Color Scheme

I just found out that some web browsers can detect theme colors on the device system.

This is very helpful for implementing color mode in web applications. In css, we can detect user's theme preference by using media query:

@media (prefers-color-scheme: dark) {
  .dark {
    background-color: black;
    color: white;
  }
}

We can also detect if the user's web browser supports it or not.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  var queryMedia = window.matchMedia('(prefers-color-scheme: dark)');
  if (queryMedia.matches) {
    setDark();
  } else {
    setLight();
  }
} else {
  setLight();
}

Commas as Thousands Separators

commas as Thousands Separatos

Returns numbers separated by commas. It can also help the user to know quickly what the number will be if the value is very large.

const numberWithCommas = (x: number) => {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};

Continued development

In order to test my skills and adapt to the provided design, I think I need to add some features to this project to make it more relevant.

Reset Region Filter Button

Reset Region Filter Button

I'm trying to make it look exactly the same as the available design. The select box is a unique part.

Before the user selects a region, the text shown is a label i.e., filter by region. However, when the user chooses, the label text is not included in the selection. This is very interesting.

So, I applied it to the code. And lets me add a Reset Button if the user wants to cancel the filter.

Highlight Search Keywords

Highlight Search Keywords I've also added a highlight for keywords that match the name of the country being searched for. By using a function from JavaScript, namely .replace().

const MarkText = ({ text, keyword }) => {
  if (keyword !== '') {
    const splitterText = '___{$#(!VMV!)#$}___';
    const regExpKeyword = new RegExp(keyword, 'gi');

    // Replacement with string
    const replace = text.replaceAll(
      regExpKeyword,
      `${splitterText}$&${splitterText}`
    );

    const split = replace.split(splitterText);

    return (
      <>
        {split.map((word, index) => {
          if (word.toLowerCase() === keyword.toLowerCase())
            return <mark key={index}>{word}</mark>;
          return word;
        })}
      </>
    );
  }
  return <>{text}</>;
};

Scroll Up Button

Scroll to Top

I didn't create a navbar with a fixed position on top. So when a user has reached the bottom of the page and they want to change a keyword or filter by a region, the user needs to go to the top of the page manually.

Therefore, I created a button that when the user presses the button, they will be directly directed to the top of the page. I think this is also often seen on the web and other blogs.

const handleClick = () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth',
  });
};

Useful resources

Author

Acknowledgments

Many thanks to anyone who provided feedback.

Releases

No releases published

Packages

No packages published