React Color Picker Component
This challenge asks you to build a functional color picker component in React using TypeScript. A color picker is a common UI element allowing users to select a color visually, and it's a fundamental building block for many applications involving customization and design. This exercise will test your understanding of React component creation, state management, event handling, and basic UI design.
Problem Description
You need to create a React component called ColorPicker that allows users to select a color from a predefined palette and displays the selected color. The component should:
- Display a Color Palette: Show a series of color swatches (e.g., divs) representing different colors. Each swatch should be clickable.
- Maintain Selected Color State: Use React state to store the currently selected color.
- Update Selected Color: When a user clicks a color swatch, update the component's state to reflect the newly selected color.
- Display Selected Color: Show a larger preview of the currently selected color.
- Provide a Color Name (Optional): Display the hex code of the selected color.
Key Requirements:
- The component must be written in TypeScript.
- The color palette should consist of at least 5 distinct colors.
- The component should be reusable and accept a prop to customize the color palette (optional, but recommended for good design).
- The component should handle clicks on the color swatches correctly.
- The component should render correctly and be visually appealing.
Expected Behavior:
- Initially, a default color should be selected (e.g., white).
- Clicking a color swatch should change the selected color preview and the displayed hex code (if implemented).
- The component should re-render whenever the selected color changes.
Edge Cases to Consider:
- What happens if the color palette prop is empty or null? (Handle gracefully, perhaps by displaying a message).
- Ensure the color swatches are visually distinct and easy to click.
- Consider accessibility (e.g., sufficient contrast between the swatch and its background).
Examples
Example 1:
Input: No props passed to ColorPicker
Output: A component displaying a default color (e.g., white) and a palette of 5 colors. Clicking a color in the palette updates the preview to that color.
Explanation: The component initializes with a default color and renders the palette. Click events on the palette update the state and trigger a re-render.
Example 2:
Input: ColorPicker( { palette: ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF'] } )
Output: A component displaying a default color (e.g., white) and a palette of the provided colors. Clicking a color in the palette updates the preview to that color.
Explanation: The component receives a custom palette as a prop and uses it to render the color swatches.
Example 3: (Edge Case)
Input: ColorPicker( { palette: [] } )
Output: A component displaying a default color (e.g., white) and a message indicating that no colors are available in the palette.
Explanation: The component handles the case where the palette is empty by displaying an appropriate message instead of crashing or rendering nothing.
Constraints
- Component Size: The component should be relatively small and focused on the color picking functionality. Avoid unnecessary complexity.
- Palette Size: The palette should contain at least 5 colors.
- Performance: The component should render efficiently, even with a larger palette (though a very large palette is not expected). Avoid unnecessary re-renders.
- Dependencies: You are allowed to use standard React and TypeScript features. Avoid external libraries for this challenge.
Notes
- Consider using functional components and hooks (e.g.,
useState) for managing state. - You can use inline styles or CSS classes to style the component.
- Think about how to make the component reusable and configurable. Passing the color palette as a prop is a good starting point.
- Focus on creating a clear, concise, and well-structured component. Code readability is important.
- The hex code display is optional, but it's a nice addition for usability.