Creating UI Components
Introduction: The Role of Foundational UI Components
Welcome back! In the previous lesson, you learned how to set up a consistent layout and client-side routing for your React app. Now that you have a solid structure, it’s time to focus on the building blocks of your user interface: foundational UI components.
Foundational UI components are small, reusable pieces of your app’s interface. They help you keep your code organized, make your app look consistent, and save you time when building new features. In this lesson, you will learn how to create three common UI components: a loading spinner, a search input, and a pagination control. These components are used in many real-world applications, and you will see how to build and use them in your own projects.
Building a Spinner Component
Let’s start by creating a Spinner component. A spinner is a small animation that shows users something is loading. This is helpful when you are waiting for data from a server or when an action takes a moment to complete.
Here is the code for a simple Spinner component:
Explanation:
- The
Spinnerfunction returns adivcontaining an SVG. The SVG is styled to spin, creating a loading animation. - The
aria-label="Loading"attribute helps screen readers understand what this element means, making your app more accessible. - The
classNamevalues use Tailwind CSS utility classes for styling and animation. On CodeSignal, Tailwind is pre-installed, so you do not need to set it up yourself.
Output:
When you use <Spinner /> in your app, you will see a spinning blue circle, indicating that something is loading.
The outer div uses flex, justify-center, and items-center to center the spinner, while the p-4 padding prevents the SVG from feeling cramped; the svg spins because Tailwind’s animate-spin applies a keyframed rotation, and the color comes from text-sky-400, which sets currentColor so both the circle with stroke="currentColor" and the wedge path with fill="currentColor" share the same hue; the visual effect of a “missing slice” comes from rendering a full faint ring (opacity-25 stroke) behind a brighter arc (opacity-75 fill), which makes the rotation obvious without extra images or GIFs, and the accessible label (“Loading”) lets tests target it with queries like getByLabelText('Loading') while remaining visually minimal.
