Hone logo
Hone
Problems

Interactive Spreadsheet Grid in React with TypeScript

This challenge asks you to build a simplified, interactive spreadsheet grid using React and TypeScript. The grid should allow users to input data into cells, and the data should be stored and displayed correctly. This is a foundational exercise for understanding state management, component composition, and event handling in React, and is a stepping stone to more complex data visualization and manipulation applications.

Problem Description

You are tasked with creating a React component that renders a spreadsheet grid. The grid should be a square, with a configurable number of rows and columns. Each cell in the grid should be an input field where the user can enter text. The component should maintain an internal state representing the data in the grid, updating this state whenever a user modifies a cell's content. The grid should visually display the data stored in the state.

Key Requirements:

  • Dynamic Grid Size: The grid should be configurable via a rows and columns prop.
  • Editable Cells: Each cell should be an <input> element that allows the user to type text.
  • State Management: The component must maintain an internal state (using useState) to store the data in the grid. This state should be a 2D array of strings, where each string represents the content of a cell.
  • Real-time Updates: When a user types into a cell, the grid's data and display should update immediately.
  • Clear Visual Representation: The grid should be visually appealing and easy to understand. Basic styling (borders, padding) is expected.

Expected Behavior:

  1. When the component mounts, it should render a grid with the specified number of rows and columns.
  2. Each cell should initially be empty.
  3. When a user types into a cell, the content of that cell in the internal state should be updated.
  4. The grid should re-render to reflect the updated data in the state.
  5. The grid should handle changes to the rows and columns props gracefully, re-rendering with the new dimensions.

Edge Cases to Consider:

  • Invalid Input: While you don't need to implement strict validation, consider how the grid will behave if a user enters a very long string into a cell. The input field should allow for reasonable length input.
  • Zero Rows/Columns: Handle the case where rows or columns is zero. The grid should not render anything in this scenario.
  • Large Grid Sizes: While not a primary focus, consider how the component might perform with very large grid sizes (e.g., 100x100). Optimization is not required for this challenge, but awareness is good.

Examples

Example 1:

Input: rows=3, columns=4
Output: A 3x4 grid with empty input fields in each cell.
Explanation: The component renders a grid with 3 rows and 4 columns, each cell containing an empty input field.

Example 2:

Input: rows=2, columns=2, initialData=[["Hello", "World"], ["React", "TypeScript"]]
Output: A 2x2 grid where the first cell contains "Hello", the second "World", the third "React", and the fourth "TypeScript".
Explanation: The component renders a grid initialized with the provided data.

Example 3: (Edge Case)

Input: rows=0, columns=5
Output: Nothing is rendered.
Explanation: The component handles the case where the number of rows is zero by not rendering the grid.

Constraints

  • Grid Size: The maximum value for rows and columns is 20.
  • Input Type: The input fields should accept only string input.
  • Performance: While optimization is not a primary goal, the component should render reasonably quickly for grid sizes up to 20x20. Avoid unnecessary re-renders.
  • Dependencies: You are allowed to use only React and TypeScript. No external libraries are permitted.

Notes

  • Consider using a functional component with the useState hook for state management.
  • Think about how to efficiently update the state when a cell's content changes. Directly mutating the state array is generally discouraged in React.
  • You can use CSS for basic styling, but complex styling is not required. Focus on functionality first.
  • The initialData prop (optional) should be a 2D array of strings with the same dimensions as the grid. If not provided, the grid should be initialized with empty strings.
  • The component should accept rows, columns, and an optional initialData prop.
Loading editor...
typescript