Skip to content

Refactor breadcrumbs to shared component - #6118

Draft
VPS-julia wants to merge 10 commits into
mainfrom
claude/grill-me-skill-props-g9idnn
Draft

Refactor breadcrumbs to shared component#6118
VPS-julia wants to merge 10 commits into
mainfrom
claude/grill-me-skill-props-g9idnn

Conversation

@VPS-julia

Copy link
Copy Markdown
Contributor

Summary

Consolidate breadcrumb implementations by extracting a shared, responsive Breadcrumbs component that both StackBreadcrumbs and ToolbarBreadcrumbs now use. This unifies their appearance and behavior while reducing code duplication.

Key Changes

  • New shared Breadcrumbs component (packages/admin/admin/src/common/breadcrumbs/Breadcrumbs.tsx):

    • Responsive component that renders desktop or mobile UI based on breakpoint
    • Accepts breadcrumb items, link component, and icon customization
    • Supports optional start adornment (e.g., back button)
    • Configurable overflow label
  • Desktop breadcrumbs (DesktopBreadcrumbs.tsx):

    • Displays full breadcrumb trail on desktop
    • Shows overflow menu (ellipsis button) when items don't fit
    • Uses width measurement layer to detect overflow without affecting layout
  • Mobile breadcrumbs (MobileBreadcrumbs.tsx):

    • Compact mobile UI with ellipsis and current item
    • Expandable menu showing full breadcrumb tree with indentation
    • Supports SPA navigation (previously reloaded page)
  • Refactored StackBreadcrumbs:

    • Now delegates to shared Breadcrumbs component
    • Maintains backward-compatible props (separator, overflowLinkText)
    • Simplified implementation with removed utility functions
  • Refactored ToolbarBreadcrumbs:

    • Now delegates to shared Breadcrumbs component
    • Maintains backward-compatible props (iconMapping)
    • Removed 300+ lines of custom markup and styling
  • Extracted utilities:

    • useBreadcrumbsOverflow hook for calculating visible/hidden items
    • getElementOuterWidth utility moved to shared location
    • Centralized slot definitions in Breadcrumbs.slots.ts

Implementation Details

  • Both components now use the same responsive logic and styling
  • Desktop overflow detection uses a hidden measurement layer to avoid layout thrashing
  • Mobile menu displays breadcrumb hierarchy with visual indentation
  • All icon customization flows through iconMapping prop
  • Maintains full slot customization support via slotProps

https://claude.ai/code/session_015gY3q94kFcTgFNoYMdYZUx

juliawegmayr and others added 10 commits December 23, 2025 15:00
Co-authored-by: Ricky James Smith <jamesricky@me.com>
…rumbs

Merge `main` into `feature/admin-breadcrumbs`
## Description

Mobile adaptions for the new Breadcrumbs component:

- Only display current item
- If there are more than one item, `. . .` should be displayed
- A chevron is added 
- On click of the chevron or the `. . .` a menu expands, that displays
all items of the breadcrumbs


## Acceptance criteria

- [x] I have verified if my change requires [an
example](https://github.com/vivid-planet/comet/blob/HEAD/CONTRIBUTING.md#example)
- [x] I have verified if my change requires [a
changeset](https://github.com/vivid-planet/comet/blob/HEAD/CONTRIBUTING.md#changeset)
- [x] I have verified if my change requires
[screenshots/screencasts](https://github.com/vivid-planet/comet/blob/HEAD/CONTRIBUTING.md#screenshotsscreencasts)

## Screenshots/screencasts

One item:
<img width="279" height="470" alt="Screenshot 2026-06-15 at 13 22 59"
src="https://github.com/user-attachments/assets/c717f405-655c-45ac-ba92-1ca886c9b80f"
/>



Multiple items:
<img width="278" height="475" alt="Screenshot 2026-06-15 at 13 19 01"
src="https://github.com/user-attachments/assets/f2f1b39e-57b9-4b08-b18a-0c4ed2840aae"
/>


<img width="280" height="474" alt="Screenshot 2026-06-15 at 13 21 54"
src="https://github.com/user-attachments/assets/9a4dc3ab-0586-48b0-ab6f-41d6179d93c8"
/>



## Further information

-   Task: https://vivid-planet.atlassian.net/browse/COM-2716

---------

Co-authored-by: Julia Wegmayr <julia.wegmayr@vivid-planet.com>
Co-authored-by: Ricky James Smith <jamesricky@me.com>
Collapse middle items into an overflow ellipsis when they don't fit,
always keeping the root and the current page. Widths are measured and
the fit is computed right-to-left so the current item is never clipped;
it truncates when space runs out. Clicking the ellipsis opens a dropdown
listing the collapsed items; on mobile the existing page-tree dropdown is
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The items were measured inside the visible container. That container is
`overflow: hidden` and the current item is the only one that may shrink, so as
soon as the items overflowed, the measured widths added up to exactly the
container width. The overflow was therefore never detected and the current page
truncated instead of collapsing its parents.

Measure the items in a hidden layer with `width: max-content` instead, where
nothing shrinks, and collapse them as the design requires: parent items move
into the overflow menu first, the root follows once it no longer fits next to
the ellipsis and the current page, and only then does the current page truncate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The overflow menu was rendered unconditionally and merely kept closed via
its `open` prop. That hid a glitch: `isOverflowMenuOpen` was never reset, so
opening the menu and then widening the viewport until nothing overflows
closed the menu but left the state set. Narrowing again re-opened it without
any user interaction.

Render the menu only when there are hidden items and reset the open state
once the last item leaves the menu.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Breadcrumbs component

Both components maintained their own breadcrumb markup, duplicating the
responsive/overflow logic that the shared Breadcrumbs component already
provides. Rebuild them as thin wrappers that read the stack breadcrumbs and
delegate rendering to Breadcrumbs, unifying their look and behavior.

To cover the two use cases, add three props to Breadcrumbs:
- linkComponent (default "a") so consumers can inject a router-aware link
  (BreadcrumbLink) for SPA navigation; the component stays router-agnostic.
  This also makes the mobile overflow menu navigate instead of reloading.
- startAdornment for a leading element (StackBreadcrumbs' back button),
  rendered outside the mobile toggle button to avoid nested interactive HTML.
- overflowLabel to keep StackBreadcrumbs' overflowLinkText working.

StackBreadcrumbs keeps its separator/overflowLinkText props and backButton/
backButtonSeparator slots; ToolbarBreadcrumbs keeps its iconMapping prop.
Their deep slotProps/styleOverrides now use the Breadcrumbs slots; update the
one in-repo consumer (AdminTabsTabContent) accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gY3q94kFcTgFNoYMdYZUx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants