Hone logo
Hone
Problems

Interactive Resizable Column Table in React

This challenge asks you to build a React component that displays data in a table format with resizable columns. Users should be able to drag the column dividers to adjust the width of each column dynamically, creating a flexible and user-friendly data presentation. This is a common requirement in data dashboards and management applications where users need to customize their view.

Problem Description

You are tasked with creating a ResizableTable component in React using TypeScript. The component should accept an array of data objects as a prop, where each object represents a row in the table. The component should also accept an array of column headers as a prop, defining the columns to be displayed. Each column should be resizable by dragging its header divider.

What needs to be achieved:

  • Display the data in a table format.
  • Allow users to resize columns by dragging the dividers between column headers.
  • Maintain the resized column widths across re-renders.
  • Handle different data types gracefully (strings, numbers, etc.).

Key Requirements:

  • Resizable Headers: Column headers should have a visual divider that users can drag to resize the column.
  • Dynamic Widths: Column widths should change dynamically as the user drags the dividers.
  • Persistent Widths: Resized column widths should be stored and applied on subsequent re-renders. Consider using localStorage or a state management solution for persistence.
  • Responsive Design: While not strictly required, consider how the table will behave on smaller screens.
  • Error Handling: Handle cases where the data doesn't match the column headers (e.g., missing data fields).

Expected Behavior:

  • When the user drags a column divider, the width of that column should change smoothly.
  • The table should reflow to accommodate the new column widths.
  • Resized column widths should be saved and restored when the component re-renders.
  • The table should display data correctly for various data types.
  • If a data object is missing a field corresponding to a column header, display a reasonable placeholder (e.g., "N/A").

Edge Cases to Consider:

  • Dragging a divider beyond the minimum or maximum allowed column width.
  • Resizing columns when the table is very wide or very narrow.
  • Handling empty data arrays.
  • Handling cases where the number of columns in the data doesn't match the number of column headers.
  • Performance with very large datasets (consider virtualization if necessary, though not required for this challenge).

Examples

Example 1:

Input: data = [{name: "Alice", age: 30, city: "New York"}, {name: "Bob", age: 25, city: "London"}]
columnHeaders = ["Name", "Age", "City"]
Output: A table with three columns: "Name", "Age", and "City".  The user can drag the dividers between the headers to resize the columns.
Explanation: The table displays the data provided, and the user can interactively resize the columns.

Example 2:

Input: data = [{name: "Alice", age: 30}, {name: "Bob", age: 25}]
columnHeaders = ["Name", "Age", "City"]
Output: A table with three columns: "Name", "Age", and "City". The "City" column will display "N/A" for both rows.
Explanation: The data is missing the "City" field, so the component displays "N/A" as a placeholder.

Example 3: (Edge Case)

Input: data = []
columnHeaders = ["Name", "Age", "City"]
Output: An empty table with the specified column headers.
Explanation: The table is empty because there is no data to display.

Constraints

  • Data Size: The data array should contain a maximum of 100 objects.
  • Column Count: The number of column headers should match the number of fields in each data object (or provide a default value for missing fields).
  • Performance: The resizing operation should be reasonably smooth (avoiding noticeable lag) even with the maximum data size. While virtualization isn't required, avoid inefficient re-renders.
  • Column Widths: Initial column widths should be reasonable and prevent columns from being too narrow to display content. Minimum column width should be 100px. Maximum column width should be 500px.

Notes

  • Consider using CSS for styling and layout.
  • You can use any React libraries you are comfortable with (e.g., styled-components, Material-UI, etc.), but the core resizing logic should be implemented manually.
  • Focus on the resizing functionality and the dynamic updating of column widths. Detailed styling is less important than correct behavior.
  • Think about how to efficiently update the table when a column is resized. Avoid unnecessary re-renders.
  • The persistence of column widths can be implemented using localStorage or a state management library like Redux or Zustand. A simple useState solution is acceptable for this challenge.
Loading editor...
typescript