Implement a Dynamic Breadcrumb Navigation Component in React
The goal of this challenge is to build a reusable React component that displays a breadcrumb navigation trail. This component will dynamically update based on an array of navigation items, allowing users to easily understand their current location within a hierarchical structure and navigate back to previous levels. This is a common UI pattern found in many web applications to improve user experience and site navigation.
Problem Description
You are tasked with creating a React functional component named Breadcrumbs. This component should accept an array of navigation items as a prop and render them as a series of clickable links, separated by a delimiter.
Key Requirements:
- Dynamic Rendering: The breadcrumb trail should be generated based on the provided
itemsprop. - Clickable Links: Each breadcrumb item (except possibly the last one) should be a clickable link.
- Delimiter: A separator (e.g., ">" or "/") should be displayed between breadcrumb items.
- Styling: Basic styling should be applied to make the breadcrumbs visually distinct and navigable.
- Accessibility: Ensure the component is accessible (e.g., using appropriate ARIA attributes).
- Last Item: The last item in the breadcrumb trail should typically not be a link, indicating the current page.
Expected Behavior:
When the Breadcrumbs component receives an array of navigation items, it should render them sequentially. For each item, it should display its label and, if it's not the last item, render it as an anchor tag (<a>) that navigates to a specified URL. The last item should be displayed as plain text.
Edge Cases:
- Empty Array: What happens if the
itemsprop is an empty array? - Single Item Array: How should a breadcrumb with only one item be rendered?
Examples
Example 1:
Input:
items = [
{ label: "Home", url: "/" },
{ label: "Products", url: "/products" },
{ label: "Electronics" }
]
Output: (Visual representation of the rendered HTML)
<nav aria-label="breadcrumb">
<ol style="list-style: none; padding: 0; margin: 0; display: flex;">
<li style="margin-right: 8px;">
<a href="/" style="text-decoration: none; color: blue;">Home</a>
</li>
<li style="margin-right: 8px;">
<span style="margin: 0 4px;">></span>
</li>
<li style="margin-right: 8px;">
<a href="/products" style="text-decoration: none; color: blue;">Products</a>
</li>
<li style="margin-right: 8px;">
<span style="margin: 0 4px;">></span>
</li>
<li aria-current="page">
<span style="font-weight: bold;">Electronics</span>
</li>
</ol>
</nav>
Explanation: The "Home" and "Products" items are rendered as clickable links. The "Electronics" item, being the last, is displayed as plain text with bold styling to indicate it's the current location. A ">" symbol is used as a delimiter.
Example 2:
Input:
items = [
{ label: "Dashboard" }
]
Output: (Visual representation of the rendered HTML)
<nav aria-label="breadcrumb">
<ol style="list-style: none; padding: 0; margin: 0; display: flex;">
<li aria-current="page">
<span style="font-weight: bold;">Dashboard</span>
</li>
</ol>
</nav>
Explanation: When there's only one item, it's rendered as the current page without any delimiters or links.
Example 3:
Input:
items = []
Output: (Visual representation of the rendered HTML)
<nav aria-label="breadcrumb">
<ol style="list-style: none; padding: 0; margin: 0; display: flex;">
<!-- No list items rendered -->
</ol>
</nav>
Explanation:
If the items array is empty, no breadcrumb items should be rendered.
Constraints
- The
itemsprop will be an array of objects. Each object will have at least alabelproperty (string). - Optionally, an object can have a
urlproperty (string) for navigation. - The component should be implemented as a functional component using React Hooks.
- TypeScript should be used for type safety.
- Avoid external libraries for the core breadcrumb logic. Basic styling can be inline or via simple CSS classes.
Notes
- Consider the semantic HTML elements to use for accessibility (e.g.,
<nav>,<ol>,<li>,aria-label,aria-current). - The delimiter character can be a prop or a hardcoded value, but flexibility is encouraged.
- Think about how to handle the
urlprop – if it's missing, the item should not be a link. - The last item should visually indicate it's the current page.
- You can define the type for the
itemsprop using TypeScript interfaces.