Interactive Mind Map Component in React with TypeScript
This challenge asks you to build a basic, interactive mind map component using React and TypeScript. Mind maps are powerful tools for visualizing information and brainstorming, and creating a reusable component allows for easy integration into various applications. The component should allow for adding, deleting, and rearranging nodes, providing a dynamic and engaging user experience.
Problem Description
You are tasked with creating a React component that renders a mind map. The mind map will be represented as a tree structure of nodes. Each node will have a title and can have child nodes. The component should allow users to:
- Add Nodes: Users should be able to add new nodes to existing nodes or as root nodes.
- Delete Nodes: Users should be able to delete nodes (and all their children).
- Rearrange Nodes: Users should be able to drag and drop nodes to change their position within the mind map.
- Visual Representation: The mind map should be visually appealing and easy to understand, with clear connections between nodes.
Key Requirements:
- Data Structure: Define a TypeScript interface for a
MindMapNodewith properties forid(string),title(string), andchildren(an array ofMindMapNodeobjects). - Component Structure: Create a React component that accepts a root
MindMapNodeas a prop. - Drag and Drop: Implement drag and drop functionality using a library like
react-dndor a custom implementation. For simplicity, a custom implementation is preferred. - State Management: Use React's state management (useState, useReducer) to manage the mind map data.
- Rendering: Render the mind map recursively, displaying each node's title and allowing for the addition of child nodes.
Expected Behavior:
- The component should render the initial mind map structure provided as a prop.
- Adding a node should update the state and re-render the mind map with the new node.
- Deleting a node should update the state and re-render the mind map without the deleted node.
- Rearranging nodes should update the state and re-render the mind map with the new node positions.
- The visual representation should be clear and intuitive, with connections between parent and child nodes.
Edge Cases to Consider:
- Empty mind map (no root node).
- Deleting a node with children.
- Adding a node to a node that already has the maximum number of children (optional, can be a future enhancement).
- Performance with a large number of nodes (consider optimization techniques if necessary).
Examples
Example 1:
Input:
const initialMindMap: MindMapNode = {
id: 'root',
title: 'Project Brainstorm',
children: [
{ id: 'task1', title: 'Research', children: [] },
{ id: 'task2', title: 'Design', children: [] }
]
};
Output:
A React component rendering a mind map with a root node "Project Brainstorm" and two child nodes "Research" and "Design". Each node is visually distinct and connected to its parent.
Explanation: The component receives the `initialMindMap` object and recursively renders the nodes and their children.
Example 2:
Input:
(After user interaction - adding a child to 'Research')
const updatedMindMap: MindMapNode = {
id: 'root',
title: 'Project Brainstorm',
children: [
{ id: 'task1', title: 'Research', children: [{id: 'subtask1', title: 'Gather Data', children: []}] },
{ id: 'task2', title: 'Design', children: [] }
]
};
Output:
The React component re-renders, now displaying a "Research" node with a child node "Gather Data".
Explanation: The state is updated with the `updatedMindMap` object, triggering a re-render of the component and its child nodes.
Example 3: (Edge Case - Empty Mind Map)
Input:
const emptyMindMap: MindMapNode = null;
Output:
A message indicating that the mind map is empty, or a placeholder element.
Explanation: The component handles the case where the input is null or undefined, preventing errors and providing a user-friendly experience.
Constraints
- Time Limit: 4 hours
- Dependencies: You can use any standard React libraries (e.g.,
react-dndis optional, but a custom drag and drop implementation is preferred). Keep external dependencies to a minimum. - Node Limit: The mind map should be able to handle at least 100 nodes without significant performance degradation.
- TypeScript: The entire solution must be written in TypeScript.
- Code Quality: The code should be well-structured, readable, and maintainable.
Notes
- Focus on the core functionality of adding, deleting, and rearranging nodes. Styling can be kept minimal for this challenge.
- Consider using a recursive approach to render the mind map.
- Think about how to efficiently update the state when nodes are added, deleted, or rearranged.
- For drag and drop, consider using a simple implementation that involves tracking the dragged node's ID and updating the state accordingly. You don't need to implement a full-featured drag and drop library unless you are comfortable with it.
- Error handling is not a primary focus, but consider how your component will behave with invalid input.