Hone logo
Hone
Problems

React Skeleton Loader Component

This challenge requires you to implement a reusable Skeleton Loader component in React using TypeScript. Skeleton loaders are a common UI pattern used to improve the perceived performance of an application by showing placeholder elements while actual content is being fetched. This provides a better user experience than a blank screen or a simple spinner.

Problem Description

Your task is to create a React component called SkeletonLoader that renders placeholder "skeleton" elements. This component should be flexible enough to represent various content structures, such as lists of items, cards, or even simple text blocks.

Key Requirements:

  1. Component Structure: Create a functional React component named SkeletonLoader.
  2. Props: The component should accept props to customize its appearance and behavior. Consider props for:
    • type: To specify the kind of skeleton to render (e.g., 'text', 'image', 'card', 'list').
    • count: The number of repeating elements for types like 'list' or 'card'.
    • width: The width of the skeleton element.
    • height: The height of the skeleton element.
    • className: To allow for custom styling via CSS classes.
    • animated: A boolean to enable/disable the shimmering animation.
  3. Rendering Logic: Based on the type prop, render appropriate placeholder elements.
    • text: Renders a rectangular bar representing a line of text.
    • image: Renders a square or rectangular placeholder for an image.
    • card: Renders a typical card structure with an image placeholder and text placeholders.
    • list: Renders multiple instances of a specified element type (e.g., multiple 'text' lines).
  4. Animation: Implement a subtle shimmering animation for the skeleton elements when animated is true. This can be achieved using CSS.
  5. TypeScript: Ensure the component is written in TypeScript with proper type definitions for props.
  6. Reusability: The component should be easily integrated into different parts of an application.

Expected Behavior:

  • When SkeletonLoader is used, it should display visual placeholders that mimic the layout of the content that will eventually load.
  • The placeholders should have dimensions appropriate for the content they represent.
  • The animation should create a smooth, unobtrusive visual effect.

Edge Cases to Consider:

  • What happens if count is 0 or negative?
  • What if width or height are not provided? Default values should be sensible.
  • How does the list type behave when count is 1?
  • Ensure the CSS for animation is encapsulated and doesn't clash with other styles.

Examples

Example 1: Basic Text Skeleton

Input:
<SkeletonLoader type="text" width="200px" height="16px" animated={true} />

Output:
A single animated, gray rectangular bar of 200px width and 16px height.

Explanation: Renders a placeholder for a single line of text with the specified dimensions and animation.

Example 2: List of Text Skeletons

Input:
<SkeletonLoader type="list" count={3} width="80%" height="14px" animated={false} />

Output:
Three non-animated, gray rectangular bars, each 80% width and 14px height, stacked vertically.

Explanation: Renders a list of three text placeholders, each taking up 80% of its container's width and having a height of 14px. No animation is applied.

Example 3: Card Skeleton

Input:
<SkeletonLoader type="card" width="300px" height="200px" animated={true} />

Output:
A styled card-like container. Inside, there's a placeholder for an image (e.g., 100% width, 60% height) and below it, two or three animated text placeholders for title and description.

Explanation: Renders a typical card structure with an image placeholder and multiple text placeholders for content, all with animation.

Constraints

  • The component must be implemented using React and TypeScript.
  • Styling should be primarily handled using CSS, either inline styles or CSS modules/classes. Avoid inline styles for complex animations.
  • The solution should aim for a clean, modular, and readable codebase.
  • The animation should be performant and not cause UI jank.

Notes

  • Consider using CSS keyframes for the shimmering animation.
  • Think about how you'll structure the rendering logic for different type props. A series of conditional rendering blocks or a mapping approach could work.
  • For the card type, you'll need to define a reasonable default layout for its internal elements (image and text).
  • When implementing the list type, ensure each item in the list is rendered correctly with the provided width and height.
  • The default styling for the skeleton elements should be a neutral gray color.
Loading editor...
typescript