Hone logo
Hone
Problems

React Button Component with Variants

This challenge focuses on building a reusable React button component that supports different visual styles (variants) through props. Creating such a component is a common task in UI development, promoting code reusability and maintainability by centralizing button styling and behavior. You'll be using TypeScript to ensure type safety and improve code clarity.

Problem Description

You are tasked with creating a Button component in React using TypeScript. This component should accept the following props:

  • children: The content to be displayed inside the button (e.g., text, icons).
  • variant: A string representing the button's visual style. Supported variants are: "primary", "secondary", and "outline". The default variant should be "primary".
  • onClick: A function to be executed when the button is clicked.
  • disabled: A boolean indicating whether the button is disabled. Defaults to false.
  • className: (Optional) A string of CSS class names to apply to the button.

The component should render a <button> element with appropriate styling based on the variant prop. The styling should include different background colors, text colors, and border styles for each variant. When disabled is true, the button should be visually disabled (e.g., grayed out) and prevent clicks. The className prop should be applied to the button element.

Expected Behavior:

  • The component should render a button element.
  • The button's appearance (background color, text color, border) should change based on the variant prop.
  • The onClick function should be called when the button is clicked (unless disabled).
  • The button should be visually disabled when the disabled prop is true.
  • The className prop should be correctly applied.
  • If no variant is provided, the button should default to the "primary" variant.

Edge Cases to Consider:

  • Invalid variant prop values (handle gracefully, defaulting to "primary").
  • children prop containing React elements or other components.
  • onClick prop being null or undefined (should not cause errors).
  • className prop being null or undefined (should not cause errors).

Examples

Example 1:

Input: <Button variant="primary" onClick={() => alert("Primary Button Clicked")}>Click Me</Button>
Output: A button with a blue background, white text, and no border, displaying "Click Me" and triggering an alert on click.
Explanation: The button uses the "primary" variant, applying the default styling.

Example 2:

Input: <Button variant="secondary" disabled>Secondary Button</Button>
Output: A button with a gray background, white text, and no border, displaying "Secondary Button", and appearing disabled (grayed out) and unresponsive to clicks.
Explanation: The button uses the "secondary" variant and is disabled.

Example 3:

Input: <Button className="my-custom-button" onClick={() => console.log("Custom Button Clicked")}>Custom Button</Button>
Output: A button with the "primary" variant styling (default), displaying "Custom Button", triggering a console log on click, and having the CSS class "my-custom-button" applied.
Explanation: The button uses the default "primary" variant and includes a custom CSS class.

Constraints

  • The component must be written in TypeScript.
  • The styling should be implemented using CSS (either inline styles or a CSS file/module). Avoid using CSS-in-JS libraries for this challenge.
  • The component should be reusable and maintainable.
  • The component should handle invalid variant values gracefully.
  • The component should not introduce any unnecessary dependencies.
  • The component should be performant and not cause any rendering issues.

Notes

  • Consider using a CSS module or a separate CSS file to manage the button styles.
  • Think about how to make the component extensible to support additional variants in the future.
  • Focus on creating a clean and well-structured component with clear prop types.
  • You can use any React and TypeScript best practices you are familiar with.
  • The styling is not the primary focus; the core requirement is the functional component with variant handling.
Loading editor...
typescript