Interactive Monthly Calendar Component in React with TypeScript
This challenge asks you to build a basic interactive monthly calendar component using React and TypeScript. A calendar is a fundamental UI element for scheduling, planning, and displaying dates, making this a valuable exercise in component design and state management. The goal is to create a reusable component that displays the current month and allows users to navigate to previous and next months.
Problem Description
You are tasked with creating a React component called Calendar that displays a monthly calendar. The component should:
- Display the current month and year: The component should prominently display the currently selected month and year.
- Navigation: Provide "Previous" and "Next" buttons to navigate between months. Clicking these buttons should update the displayed month and year.
- Calendar Grid: Display a grid representing the days of the month. Each cell in the grid should represent a single day.
- Day Numbers: Each day cell should display the correct day number for that date.
- Date Highlighting (Optional): Consider adding a visual cue (e.g., different background color) to highlight the current date.
- Weekdays: Display the names of the weekdays (Sunday, Monday, etc.) at the top of the calendar grid.
- Empty Days: Handle the "empty" days at the beginning and end of the month (days that belong to the previous or next month). These cells should not display any day number.
Expected Behavior:
- Clicking "Previous" should decrement the month, wrapping around to December if the current month is January. The year should also decrement if necessary.
- Clicking "Next" should increment the month, wrapping around to January if the current month is December. The year should also increment if necessary.
- The calendar grid should accurately reflect the days of the week and month for the selected date.
- The component should re-render correctly when the month or year changes.
Edge Cases to Consider:
- Leap years (February 29th).
- Handling the first day of the week (Sunday or Monday - consider making this configurable).
- Ensuring the calendar grid is visually appealing and easy to understand.
Examples
Example 1:
Input: Initial state: month = 1 (January), year = 2024
Output: A calendar displaying January 2024, with the correct day numbers in each cell, and the current date (January 1st, 2024) potentially highlighted.
Explanation: The component initializes to the current month and year, and renders the calendar grid accordingly.
Example 2:
Input: User clicks "Next" button multiple times.
Output: The calendar displays subsequent months (February, March, April, etc.) and updates the year accordingly.
Explanation: The component updates its internal state (month and year) and re-renders the calendar grid to reflect the new date.
Example 3: (Edge Case)
Input: month = 12 (December), year = 2023, user clicks "Next"
Output: The calendar displays January 2024.
Explanation: The component correctly handles the month wrapping around from December to January and increments the year.
Constraints
- Component Re-renders: The component should re-render efficiently when the month or year changes. Avoid unnecessary re-renders.
- Date Calculation: You can use a library like
date-fnsormoment.jsfor date calculations, or implement your own logic. If using a library, ensure it's properly installed and imported. - Styling: Basic styling is acceptable (e.g., using CSS or styled-components). Focus on functionality over elaborate styling.
- Performance: The component should render quickly, even for large months. Avoid complex calculations within the render loop.
- Input Format: The component should accept the initial month and year as props (optional). If not provided, it should default to the current date.
Notes
- Consider using functional components and React Hooks (e.g.,
useState) for managing the component's state. - Think about how to structure your code to make it reusable and maintainable.
- Focus on the core functionality of displaying the calendar and navigating between months. Advanced features like event handling or date selection can be added later.
- The first day of the week can be hardcoded (Sunday) or made configurable via a prop.
- Error handling is not required for this challenge. Assume valid input.