Hone logo
Hone
Problems

Build a Responsive Grid System in React

This challenge asks you to implement a fundamental building block of modern web design: a responsive grid system. You will create reusable React components that allow developers to easily arrange content in a flexible and adaptive layout across different screen sizes. This skill is crucial for building visually appealing and user-friendly interfaces.

Problem Description

Your task is to create a set of React components that together form a responsive grid system. This system should allow users to define a layout with rows and columns that adjust their behavior based on the screen width.

Key Requirements:

  1. Container Component:

    • This component will wrap the entire grid.
    • It should accept a fluid prop (boolean). If fluid is true, the container should take up the full width of its parent. If false (default), it should have a maximum width and be centered.
    • It should provide a context for the Row components.
  2. Row Component:

    • This component represents a horizontal row in the grid.
    • It should arrange its Col children horizontally.
    • It should handle potential overflow issues and ensure columns fit within the row.
  3. Col Component:

    • This component represents a column within a Row.
    • It should accept props to define its width at different screen sizes. The props should follow a convention like xs, sm, md, lg, xl, where each prop specifies the number of columns the component should span out of a total of 12.
    • If a prop for a specific breakpoint is not provided, it should inherit the width from the next larger breakpoint. If no breakpoints are provided, it should default to spanning all 12 columns.
    • It should allow for offset props (e.g., smOffset, mdOffset) to create spacing between columns. These offsets should also be responsive.
    • It should accept a children prop to render its content.

Expected Behavior:

  • The layout should adapt gracefully to different viewport sizes.
  • Columns should stack vertically on smaller screens if they exceed the available width or if no specific responsive widths are defined.
  • Offsets should correctly create horizontal space.

Edge Cases:

  • A row with more than 12 columns worth of width defined across its children should be handled gracefully (e.g., columns might wrap or overflow depending on implementation choice, but should not break the layout entirely).
  • No Col components within a Row.
  • Col components with zero width.
  • Using only offset props without specifying width.

Examples

Example 1: Basic Layout

Input:
<Container>
  <Row>
    <Col xs={12} sm={6} md={4}>
      Content 1
    </Col>
    <Col xs={12} sm={6} md={4}>
      Content 2
    </Col>
    <Col xs={12} sm={12} md={4}>
      Content 3
    </Col>
  </Row>
</Container>
Output:
(Visual representation of a layout where:
- On extra-small screens (xs): All three columns stack vertically, each taking 100% width.
- On small screens (sm): Content 1 and Content 2 are side-by-side (6 columns each), Content 3 is below them.
- On medium screens (md) and larger: All three columns are side-by-side, each taking 4 columns worth of width.)

Explanation: The xs prop dictates the behavior on extra-small screens, causing columns to stack. sm and md props redefine the column widths for larger screens, making them appear side-by-side.

Example 2: With Offsets

Input:
<Container>
  <Row>
    <Col md={4} mdOffset={2}>
      Pushed Content
    </Col>
    <Col md={4}>
      Other Content
    </Col>
  </Row>
</Container>
Output:
(Visual representation of a layout on medium screens (md) and larger:
- "Pushed Content" column starts 2 columns in from the left.
- "Other Content" column follows immediately after "Pushed Content", with no gap between them.)

Explanation: The mdOffset={2} prop on the first column pushes it 2 units to the right, creating a gap before it. The total width occupied by the first column and its offset is 6 units (4 width + 2 offset).

Example 3: Fluid Container and Inherited Widths

Input:
<Container fluid>
  <Row>
    <Col lg={3}>
      Item A
    </Col>
    <Col> {/* No width specified, inherits */}
      Item B
    </Col>
    <Col lg={3}>
      Item C
    </Col>
  </Row>
</Container>
Output:
(Visual representation of a layout where:
- The container takes up the full viewport width.
- On large screens (lg): Item A takes 3 columns, Item B takes the remaining 6 columns (inheriting from `lg=3` and calculating remaining space), and Item C takes 3 columns.
- On smaller screens: Columns will stack or adjust based on default behavior.)

Explanation: The fluid prop makes the container fill the width. The second Col component without explicit width props will fill the remaining available space within the row on large screens after accounting for the lg={3} columns.

Constraints

  • The grid should be based on a 12-column system.
  • Breakpoints are typically defined as: xs (extra-small, < 576px), sm (small, ≥ 576px), md (medium, ≥ 768px), lg (large, ≥ 992px), xl (extra-large, ≥ 1200px). You can use these as common breakpoint identifiers.
  • Your components should be implemented in TypeScript.
  • The solution should focus on the core grid logic and styling; minimal CSS is expected, and you can use inline styles or CSS Modules/styled-components for styling.
  • Performance is not a critical concern for this challenge, but avoid overly complex DOM structures or excessive re-renders.

Notes

  • Consider how you will manage responsive styles. CSS media queries will be essential.
  • Think about how Row components will distribute space among their Col children.
  • The Container component can act as a context provider if that simplifies state management or prop drilling.
  • You'll likely need to simulate or handle window resizing to test responsiveness. For this challenge, focus on defining the structure and styles that would respond. You don't necessarily need to implement a live resizing hook.
  • Focus on the correct application of props and the resulting visual structure.
Loading editor...
typescript