Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
330 changes: 330 additions & 0 deletions packages/breadcrumb-trail/spec/flow-api.md

Large diffs are not rendered by default.

691 changes: 691 additions & 0 deletions packages/breadcrumb-trail/spec/flow-spec.md

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions packages/breadcrumb-trail/spec/problem-statement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# BreadcrumbTrail Problem Statement

## Problem

Users navigating hierarchically structured web applications need a way to understand their current location within the hierarchy and quickly move up to ancestor pages. This is especially important when users arrive deep in a hierarchy via search results, bookmarks, or shared links and have no context for where they are in the application's structure.

## Target Users

End users of business web applications with multi-level hierarchical navigation, such as:

- **Content management systems** where editors navigate folders, categories, and nested content
- **E-commerce admin panels** where operators drill into product catalogs, order details, and customer records
- **Documentation portals** where readers browse topic hierarchies
- **File management interfaces** where users navigate directory structures
- **Enterprise dashboards** where analysts move between organizational units, projects, and detail views

Breadcrumbs are most valuable in applications with three or more navigation levels, where the primary navigation (e.g., side nav) may not fully convey the user's current depth.

## Differentiation

### Side Navigation

Side Navigation displays the full (or expandable) navigation tree persistently in a sidebar. It is the primary navigation mechanism. Breadcrumbs are a lightweight, secondary indicator that complements Side Nav by showing the current path inline above the page content. Breadcrumbs do NOT replace Side Nav or serve as primary navigation.

### Tabs

Tabs switch between peer-level content sections (horizontal siblings). Breadcrumbs show the vertical ancestor path. These are orthogonal: a page reached via tabs may still have a breadcrumb trail showing its position in the broader hierarchy.

### Progress Indicator

Progress indicators show position in a linear, sequential multi-step process (e.g., a checkout wizard). Breadcrumbs show position in a non-linear hierarchy. Sequential step flows are out of scope for breadcrumbs.

### Browser Back Button

The back button navigates through session history (temporal). Breadcrumbs navigate the information architecture (structural). Breadcrumbs should not replicate path-based history trails.

## Use Cases

1. **Navigating up a hierarchy.** A user is viewing a deeply nested page and wants to move up to a parent or grandparent page. The breadcrumb trail shows the full path from the root to the current page, and each ancestor is a link the user can click to jump directly to that level.

*Example: A user in a documentation portal is reading an article at "Home > Developer Guide > API Reference > Authentication > OAuth2". They click "API Reference" in the breadcrumb to jump back to the API overview page.*

2. **Orienting after a deep landing.** A user arrives at a page deep in the application via a search result, a bookmarked URL, or a link shared by a colleague. They have no context for where this page sits in the application structure. The breadcrumb trail immediately communicates the page's position in the hierarchy without requiring the user to explore the navigation.

*Example: A support agent receives a link to a customer's order detail page. The breadcrumb shows "Home > Customers > Acme Corp > Orders > #10432", immediately telling them they are inside the Acme Corp customer record.*

3. **Navigating a dynamic or user-driven hierarchy.** The hierarchy is not a fixed site map but is constructed from application data. The application provides the trail dynamically, and the breadcrumb reflects whatever hierarchy the application defines.

*Example: A user browses a product catalog filtered by category. The breadcrumb shows "Electronics > Laptops > Gaming" — a path derived from the data model, not a static sitemap. If they switch to browsing by brand instead, the trail changes to "Brands > Asus > Laptops".*

## Discussion

**Q: Should breadcrumb items support sibling navigation (dropdown menus to browse sibling pages at the same level)?**

No. Breadcrumb items are plain links to ancestors only. Sibling browsing is handled by other navigation components such as Side Nav. This keeps the breadcrumb focused on its core purpose of vertical hierarchy navigation.

**Q: Should the breadcrumb scope include attribute-based trails (e.g., e-commerce filter paths), or only location-based hierarchy?**

The breadcrumb should support both a static hierarchy (reflecting the application's information architecture) and a dynamic hierarchy provided by the application. The component does not need to distinguish between the two -- it renders whatever trail the application supplies. This covers location-based paths, data-driven paths, and attribute-based paths alike.
171 changes: 171 additions & 0 deletions packages/breadcrumb-trail/spec/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# BreadcrumbTrail Requirements

## 1. Displaying the ancestor trail

The breadcrumb displays a horizontal sequence of items representing the path from the root of a hierarchy to the user's current location. Each ancestor item is a navigable link that takes the user directly to that level when activated.

*Example: A user viewing an article sees "Home > Developer Guide > API Reference > Authentication > OAuth2". Clicking "API Reference" navigates them to the API overview page.*

---

## 2. Current page indication

The last item in the trail represents the user's current location and is visually distinct from the ancestor links. It is not an interactive link — it serves as a label confirming where the user is.

*Example: In "Home > Customers > Acme Corp", the text "Acme Corp" appears in a different style (e.g., not underlined, not clickable) to show it is the current page, while "Home" and "Customers" are links.*

---

## 3. Optionally omitting the current page

The application can choose whether the current-page item is included in the trail. When omitted, the breadcrumb shows only the ancestor links leading up to (but not including) the current page.

*Example: A documentation portal shows the page title as a heading below the breadcrumb. The breadcrumb displays "Home > Developer Guide > API Reference" without repeating "Authentication" because the heading already identifies the current page.*

---

## 4. Visual separator between items

A visual separator appears between consecutive items to convey the hierarchical relationship. The separator is purely decorative and is not announced by assistive technology.

*Example: Each pair of adjacent items is separated by a forward-pointing chevron: "Home › Laptops › Gaming".*

---

## 5. Customizable separator appearance

The application can change the visual appearance of the separator to match its design language.

*Example: An application replaces the default chevron separator with a forward slash, so the trail reads "Home / Products / Laptops".*

---

## 6. Overflow collapse of intermediate items

When the trail contains more items than fit the available horizontal width, intermediate items collapse in order of ancestry — starting from the item closest to the root — until only the root and the current item remain uncollapsed. If further collapsing is still needed, the root item finally collapses as well. The current item never collapses. Collapsed items are replaced by a single overflow indicator (such as an ellipsis button).

The rationale: the root and the current item's immediate ancestors are the ones the user is most likely to want to see and navigate to, so they are preserved the longest.

*Example: A file manager path "Home > Documents > Projects > 2026 > Q1 > Reports > Summary" first collapses to "Home > … > Q1 > Reports > Summary" (hiding "Documents" and "Projects"), then to "Home > … > Reports > Summary", then to "Home > … > Summary", and finally — if even that doesn't fit — to "… > Summary".*

---

## 7. Expanding collapsed items

When items are collapsed behind the overflow indicator, the user can activate the indicator to reveal the hidden items so they can navigate to any level in the trail.

*Example: The user clicks the "…" button and sees a menu listing "Documents", "Projects", "2026", "Q1", and "Reports". They click "Q1" to navigate directly to that level.*

---

## 8. Items may display icons

Each breadcrumb item can optionally display an icon alongside its text label. Icons are supplementary — the text label remains the primary identifier.

*Example: The root item shows a home icon next to the label "Home", while a category item shows a folder icon next to "Documents".*

---

## 9. Dynamic trail updates

The breadcrumb trail can be updated at runtime to reflect a hierarchy that changes based on application state, user navigation, or data-driven paths. The component renders whatever trail the application provides, without assuming a fixed sitemap.

*Example: A product catalog breadcrumb shows "Electronics > Laptops > Gaming" when browsing by category. When the user switches to browsing by brand, the application updates the trail to "Brands > Asus > Laptops", and the breadcrumb immediately reflects the new path.*

---

## 10. Navigation landmark

The breadcrumb identifies itself as a navigation landmark so that assistive technology users can locate it among other landmarks on the page.

*Example: A screen reader user pressing a landmark shortcut finds the breadcrumb navigation region without having to read through every link on the page.*

---

## 11. Current page announced as current by assistive technology

When the current-page item is included in the trail, assistive technology announces it as the current page, distinguishing it from the ancestor links.

*Example: A screen reader user tabbing through the breadcrumb hears each ancestor announced as a link. The last item is announced as "OAuth2, current page", making clear that this is their current location rather than a navigable link.*

---

## 12. Directional separator flips in right-to-left layouts

When the component renders in a right-to-left context, directional separators (such as chevrons) flip to point in the reading direction, maintaining the visual indication of hierarchy from right to left.

*Example: In an Arabic-language application, the breadcrumb reads from right to left and the chevron separators point left instead of right, so the visual flow matches the reading direction.*

---

## 13. Flow: Default trail derived from the router hierarchy

In the Flow wrapper, instantiating a breadcrumb without configuring its items causes it to populate itself automatically from the application's router. The default strategy walks up the URL path of the current route and matches each prefix to a registered Flow route, producing one breadcrumb item per matched ancestor. The text shown for each item is the matched route's view title (the value Flow uses to set the page title for that route — typically the route's `@PageTitle`, or the title supplied dynamically by the view).

*Example: A user navigates to `/customers/acme/orders`. The orders view is annotated `@PageTitle("Orders")`, the customer detail view dynamically sets its title to "Acme Corp", the customers list view is `@PageTitle("Customers")`, and the root view is `@PageTitle("Home")`. A view that simply does `add(new BreadcrumbTrail())` shows "Home › Customers › Acme Corp › Orders" — one item per matched route, each labeled with that route's view title.*

---

## 14. Flow: Opting out of automatic trail population

The Flow wrapper lets the application disable automatic population so the breadcrumb shows only the items the application provides explicitly. Opting out is a per-instance choice and does not affect other breadcrumbs in the application.

*Example: A product catalog view builds its trail from category data rather than the URL structure. It opts the breadcrumb out of automatic population and supplies the items itself, so router-derived ancestors are not mixed in.*

---

## 15. Flow: Sitemap parent annotation overrides URL-based parent lookup

A Flow `@Route` class can carry an annotation that declares its sitemap parent. When the annotation is present, the automatic trail uses the declared parent for that view instead of inferring one from the URL hierarchy. Walking continues from the declared parent using the same rules.

*Example: A route registered at `/orders/edit/123` declares its sitemap parent as the orders list view. The breadcrumb shows "Home › Orders › Edit Order" instead of the URL-derived "Home › Orders › Edit › Edit Order".*

---

## 16. Flow: Routes can dynamically supply their breadcrumb contribution

A Flow `@Route` class can implement an interface that lets it dynamically provide what should appear in the breadcrumb for that view. The contribution is evaluated at navigation time, so it can depend on the data the view is currently showing, and it can replace the view's default item, add additional ancestors, or both.

*Example: A `CustomerView` showing customer "Acme Corp" implements the interface and returns "Acme Corp" as its own label plus an extra ancestor "Enterprise" (the customer's segment). The breadcrumb shows "Home › Customers › Enterprise › Acme Corp" instead of a generic "Home › Customers › Customer".*

---

## Discussion

Questions posed while producing this document, with the user's answers.

**Q: When the breadcrumb trail is too long to fit the available width, how should the component handle overflow?**

Collapse intermediate items progressively, starting from the item closest to the root, so the current item's immediate ancestors are preserved the longest. The root collapses only as a last resort; the current item never collapses. The rationale is that the root and the current item's nearby ancestors are the ones the user most likely wants to see or jump to.

**Q: Should breadcrumb items support displaying icons alongside their text label?**

Yes, items can optionally display an icon before their text. Useful for home icons, folder icons, etc.

**Q: On small viewports (mobile), should the breadcrumb simplify its display?**

No special mobile behavior — use the same overflow/collapse mechanism as on desktop.

**Q: Which variants are in scope for this component?**

Both web component and Flow (Java) wrapper — the standard for new Vaadin components.

**Q: Should long item labels be truncated with an ellipsis?**

No. Truncation of individual labels is not a component-level requirement — removed from scope.

**Q: Should the navigation landmark have a default label (e.g., "Breadcrumb")?**

No. The component identifies itself as a navigation landmark but does not provide a component-specific default label.

**Q: Why does the Flow wrapper auto-populate the trail from the router by default?**

A Flow application already declares its sitemap as `@Route` classes, so requiring every view to manually build a breadcrumb duplicates information the framework already has. Defaulting to router-derived items (req 13) lets the trivial case work with zero configuration. Apps that need full control can opt out per instance (req 14).

**Q: What text does the auto-populated trail show for each item?**

Each item is labeled with the matched route's view title — i.e., whatever Flow already uses as the page title for that route (the `@PageTitle` value, or a dynamically supplied title). Reusing the existing title means a route's breadcrumb label and browser tab title stay in sync without the developer having to declare them twice.

**Q: Why support both a parent annotation and a runtime interface for influencing the trail?**

URL hierarchy alone cannot express two common cases: (a) a route whose conceptual parent differs from its URL parent — e.g., an edit view whose parent is the list view, not the URL segment "edit" (req 15) — and (b) a trail that depends on the data the view is showing, such as inserting a customer's segment as an ancestor (req 16). A static annotation handles the first cleanly without runtime cost; a runtime interface handles the second. Together they cover the cases the URL-walking default cannot.
Loading
Loading