React Timeline Component Challenge
Build a reusable and visually appealing timeline component in React using TypeScript. This component will display a series of events chronologically, making it easy for users to grasp the progression of information or a sequence of actions. This is a common UI pattern used in project management tools, event listings, and historical displays.
Problem Description
Your task is to create a React component named Timeline that accepts an array of timeline event objects and renders them in a vertical chronological order. Each event should display its date, title, and a brief description. The component should be designed with reusability and styling flexibility in mind.
Key Requirements:
- Component Structure: Create a
Timelinecomponent that accepts a prop,events, which is an array of objects. Each object in theeventsarray should conform to a defined TypeScript interface (e.g.,TimelineEvent). - TimelineEvent Interface: Define a
TimelineEventinterface with properties likedate(string or Date object),title(string), anddescription(string). - Visual Rendering:
- Display events in chronological order based on their
date. - Each event should have a visual marker (e.g., a dot or a small icon) on a central axis.
- The date, title, and description should be clearly associated with their respective markers.
- Consider how to handle potential styling differences between alternating events (e.g., left/right alignment) for better readability, though this is optional for a basic implementation.
- Display events in chronological order based on their
- Styling: The component should be styled using CSS modules or inline styles for encapsulation, and it should be easy to customize the overall look and feel.
- Reusability: The
Timelinecomponent should be generic enough to be used with different sets of event data.
Expected Behavior:
Given an array of TimelineEvent objects, the Timeline component will render a vertical list where each event is represented by a distinct visual element. The elements will be arranged from top to bottom according to their dates.
Edge Cases to Consider:
- Empty Events Array: What happens if the
eventsprop is an empty array? The component should gracefully handle this, perhaps by rendering nothing or a placeholder message. - Date Formatting: While the
TimelineEventinterface can acceptDateobjects, you might want to format them consistently for display (e.g., "YYYY-MM-DD"). - Long Descriptions: Ensure that long descriptions are handled without breaking the layout.
Examples
Example 1:
// Input Data
interface TimelineEvent {
date: string;
title: string;
description: string;
}
const eventsData: TimelineEvent[] = [
{
date: "2023-01-15",
title: "Project Kickoff",
description: "Initial meeting to define project scope and goals."
},
{
date: "2023-03-10",
title: "Milestone 1 Achieved",
description: "Completed the first phase of development and testing."
},
{
date: "2023-05-20",
title: "User Feedback Session",
description: "Gathered valuable insights from early adopters."
}
];
// Expected Rendered Output (Conceptual)
// This is a conceptual representation of the rendered HTML/JSX.
/*
<div class="timeline-container">
<div class="timeline-event">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-date">2023-01-15</div>
<div class="timeline-title">Project Kickoff</div>
<div class="timeline-description">Initial meeting to define project scope and goals.</div>
</div>
</div>
<div class="timeline-event">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-date">2023-03-10</div>
<div class="timeline-title">Milestone 1 Achieved</div>
<div class="timeline-description">Completed the first phase of development and testing.</div>
</div>
</div>
<div class="timeline-event">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-date">2023-05-20</div>
<div class="timeline-title">User Feedback Session</div>
<div class="timeline-description">Gathered valuable insights from early adopters.</div>
</div>
</div>
</div>
*/
Example 2:
// Input Data
interface TimelineEvent {
date: string;
title: string;
description: string;
}
const emptyEvents: TimelineEvent[] = [];
// Expected Rendered Output (Conceptual)
// The component should render an empty div or a placeholder, not crash.
/*
<div class="timeline-container">
<p>No events to display.</p>
</div>
*/
Constraints
- React Version: Use React 18+.
- TypeScript: Solution must be written entirely in TypeScript.
- No External Libraries (for core logic): Avoid using third-party timeline-specific libraries for the core component logic. Styling libraries (like Tailwind CSS) or UI component libraries (like Material UI) are acceptable for styling if preferred, but the timeline structure should be built from scratch.
- Performance: The component should render efficiently, especially for a large number of events.
Notes
- Consider using a
<ul>or<div>for the main timeline container. Each event could be a<li>or a nested<div>. - The visual marker and the connecting line are key aesthetic elements. Think about how to implement these.
- You might want to sort the events by date before rendering, in case the input array is not pre-sorted.
- Experiment with different CSS approaches for styling. CSS Modules offer good encapsulation.
- Think about accessibility. Ensure screen readers can correctly interpret the timeline information.