Hone logo
Hone
Problems

React Labeled Input Component

This challenge focuses on creating a reusable and accessible input component in React that is paired with a clearly associated label. This is a fundamental building block for any form-based user interface, ensuring usability and accessibility for all users.

Problem Description

Your task is to develop a React component named LabeledInput that renders an HTML <input> element along with its corresponding <label> element. The label should be programmatically associated with the input field, typically using the htmlFor attribute on the label and the id attribute on the input. This association is crucial for accessibility, allowing screen readers to announce the label when the input receives focus, and enabling users to click the label to focus the input.

Key Requirements:

  1. Component Structure: Create a functional React component named LabeledInput.
  2. Props: The component should accept at least the following props:
    • label: A string representing the text content of the label.
    • id: A unique string identifier for the input element. This will be used for htmlFor on the label.
    • ...rest: The component should accept and pass down any other standard HTML input attributes (e.g., type, placeholder, value, onChange, name, required, disabled).
  3. Rendering:
    • Render a <label> element.
    • Render an <input> element.
  4. Accessibility: The <label>'s htmlFor attribute must match the <input>'s id attribute.
  5. Reusability: The component should be designed to be easily reused for various input types and configurations.

Expected Behavior:

  • When the LabeledInput component is rendered, it should display a visible label and an input field.
  • Clicking on the label text should focus the associated input field.
  • All other standard input attributes passed as props should be correctly applied to the <input> element.

Edge Cases:

  • Consider how the component behaves with different type attributes for the input (e.g., text, password, email, number).
  • Ensure the component handles onChange and value props correctly for controlled input behavior.

Examples

Example 1: Basic Text Input

Input Props:
{
  label: "Email Address",
  id: "email",
  type: "email",
  placeholder: "Enter your email",
  value: "",
  onChange: (e) => console.log(e.target.value)
}

Rendered HTML (simplified):
<label htmlFor="email">Email Address</label>
<input id="email" type="email" placeholder="Enter your email" value="" />

Explanation: A standard email input field with a label. Clicking "Email Address" will focus the input.

Example 2: Password Input with Required Attribute

Input Props:
{
  label: "Password",
  id: "password",
  type: "password",
  required: true,
  value: "mysecretpassword",
  onChange: (e) => console.log(e.target.value)
}

Rendered HTML (simplified):
<label htmlFor="password">Password</label>
<input id="password" type="password" required value="mysecretpassword" />

Explanation: A password input field, marked as required. The htmlFor and id are correctly linked.

Example 3: Disabled Input

Input Props:
{
  label: "Username (read-only)",
  id: "username",
  type: "text",
  value: "johndoe",
  disabled: true
}

Rendered HTML (simplified):
<label htmlFor="username">Username (read-only)</label>
<input id="username" type="text" value="johndoe" disabled />

Explanation: A disabled input field. The label is still present and associated.

Constraints

  • The LabeledInput component must be a functional component using React Hooks.
  • The solution must be written in TypeScript.
  • The id prop is mandatory for the LabeledInput component to ensure proper association.
  • The label prop is mandatory.
  • The component should not introduce any unnecessary wrapper elements around the label and input.

Notes

  • Remember to use the JSX.IntrinsicElements type for the ...rest props to ensure type safety for standard HTML attributes.
  • Consider how you might structure the JSX to allow for easy styling in the future, though styling is not a primary focus of this challenge.
  • This component is a building block. Think about how it could be extended to handle different input types or error states.
Loading editor...
typescript