Hone logo
Hone
Problems

React Dashboard Layout Challenge

This challenge focuses on building a flexible and responsive dashboard layout component in React using TypeScript. A well-structured dashboard is crucial for presenting data and controls in an organized and user-friendly manner. You will create a reusable component that can adapt to different content sizes and screen resolutions.

Problem Description

Your task is to create a React component named DashboardLayout that accepts an array of "widgets" as props. Each widget should be rendered within its own defined container. The layout should automatically arrange these widgets, prioritizing a grid-like structure that scales gracefully.

Key Requirements:

  1. Component Structure: Create a functional React component named DashboardLayout that accepts a widgets prop.
  2. Widget Rendering: Each item in the widgets prop should be a React element (e.g., a <div>, another custom component) and will be rendered as a distinct "widget" within the layout.
  3. Grid Layout: The widgets should be displayed in a responsive grid. On larger screens, aim for a 3-column layout. As the screen size decreases, the number of columns should adjust (e.g., 2 columns on medium screens, 1 column on small screens).
  4. Spacing: There should be consistent spacing between widgets (both horizontally and vertically).
  5. Responsiveness: The layout must adapt to different screen sizes. Use CSS media queries or a responsive CSS framework approach (e.g., CSS Grid's repeat(auto-fit, minmax(...))).
  6. TypeScript: The component and its props must be defined using TypeScript.

Expected Behavior:

  • When provided with several widgets, they should be arranged in a grid.
  • On a wide viewport, widgets should fill up to 3 columns.
  • On a narrower viewport, widgets should stack into fewer columns or a single column.
  • Each widget should have a visually distinct container (e.g., a border, background color, padding).

Edge Cases to Consider:

  • No Widgets: The layout should render gracefully (i.e., render nothing or an empty container) if the widgets prop is an empty array or null/undefined.
  • Odd Number of Widgets: The grid should still arrange widgets as neatly as possible, even with an odd number of items.
  • Widget Size Variation: While this challenge doesn't explicitly require dynamic sizing within the layout, assume widgets themselves might have different intrinsic heights. The grid should handle this.

Examples

Example 1:

// Assume these are your widget components
const WidgetA = () => <div style={{ border: '1px solid blue', padding: '10px' }}>Widget A</div>;
const WidgetB = () => <div style={{ border: '1px solid green', padding: '10px' }}>Widget B</div>;
const WidgetC = () => <div style={{ border: '1px solid red', padding: '10px' }}>Widget C</div>;
const WidgetD = () => <div style={{ border: '1px solid orange', padding: '10px' }}>Widget D</div>;

// In your App component or parent
<DashboardLayout widgets={[<WidgetA />, <WidgetB />, <WidgetC />, <WidgetD />]} />

Output: (Conceptual visualization on a wide screen)

+-----------+-----------+-----------+
| Widget A  | Widget B  | Widget C  |
+-----------+-----------+-----------+
| Widget D  |           |           |
+-----------+-----------+-----------+

Explanation: The four widgets are arranged in a 3-column grid. Widget D starts a new row.

Example 2:

// Same widget components as above

// In your App component or parent
<DashboardLayout widgets={[<WidgetA />, <WidgetB />]} />

Output: (Conceptual visualization on a wide screen)

+-----------+-----------+
| Widget A  | Widget B  |
+-----------+-----------+

Explanation: Two widgets are arranged in the first two columns of the 3-column grid.

Example 3: (Small Screen Behavior)

If the viewport is narrow, the same input from Example 1:

// Assume these are your widget components
const WidgetA = () => <div style={{ border: '1px solid blue', padding: '10px' }}>Widget A</div>;
const WidgetB = () => <div style={{ border: '1px solid green', padding: '10px' }}>Widget B</div>;
const WidgetC = () => <div style={{ border: '1px solid red', padding: '10px' }}>Widget C</div>;
const WidgetD = () => <div style={{ border: '1px solid orange', padding: '10px' }}>Widget D</div>;

// In your App component or parent
<DashboardLayout widgets={[<WidgetA />, <WidgetB />, <WidgetC />, <WidgetD />]} />

Output: (Conceptual visualization on a small screen)

+-----------+
| Widget A  |
+-----------+
| Widget B  |
+-----------+
| Widget C  |
+-----------+
| Widget D  |
+-----------+

Explanation: On a small screen, the layout collapses to a single column, with each widget stacking vertically.

Constraints

  • The widgets prop will be an array of React elements (React.ReactNode[]) or null/undefined.
  • The number of widgets will not exceed 50.
  • The layout should be implemented using CSS Grid for efficient arrangement.
  • Avoid using external CSS framework libraries like Bootstrap or Material UI for the grid layout itself; implement the core grid logic yourself using standard CSS.

Notes

  • Consider how you will define the grid columns and rows using CSS Grid properties like grid-template-columns and gap.
  • Think about how to apply different styles based on screen sizes.
  • The actual content of the widgets is not your concern; focus on the layout container and arrangement.
  • You'll need to define the DashboardLayout component and its props interface using TypeScript.
Loading editor...
typescript