Skip to content

Commit dffe0f1

Browse files
committed
Fix up some issues.
1 parent c0f61c3 commit dffe0f1

File tree

2 files changed

+23
-52
lines changed

2 files changed

+23
-52
lines changed

packages/react/src/Breadcrumbs/Breadcrumbs.stories.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ export const OverflowMenu = () => (
3636
<Breadcrumbs.Item href="#">Home</Breadcrumbs.Item>
3737
<Breadcrumbs.Item href="#">Products</Breadcrumbs.Item>
3838
<Breadcrumbs.Item href="#">Category</Breadcrumbs.Item>
39-
<Breadcrumbs.Item href="#">Subcategory</Breadcrumbs.Item>
40-
<Breadcrumbs.Item href="#">Item</Breadcrumbs.Item>
41-
<Breadcrumbs.Item href="#">Details</Breadcrumbs.Item>
39+
<Breadcrumbs.Item href="#">SubcategorySubcategorySubcategorySubcategory</Breadcrumbs.Item>
40+
<Breadcrumbs.Item href="#">ItemItemItemItemItemItemItem</Breadcrumbs.Item>
41+
<Breadcrumbs.Item href="#">DetailsDetailsDetailsDetailsDetailsDetailsDetails</Breadcrumbs.Item>
4242
<Breadcrumbs.Item href="#" selected>
4343
Current Page
4444
</Breadcrumbs.Item>
@@ -60,7 +60,7 @@ export const OverflowMenuShowRoot = () => (
6060
)
6161

6262
export const OverflowMenuNarrowContainer = () => (
63-
<div style={{width: '200px', border: '1px solid #ccc', padding: '8px'}}>
63+
<div style={{width: '350px', border: '1px solid #ccc', padding: '8px'}}>
6464
<Breadcrumbs overflow="menu">
6565
<Breadcrumbs.Item href="#">Home</Breadcrumbs.Item>
6666
<Breadcrumbs.Item href="#">Products</Breadcrumbs.Item>

packages/react/src/Breadcrumbs/Breadcrumbs.tsx

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const BreadcrumbsMenuItem = React.forwardRef<HTMLButtonElement, BreadcrumbsMenuI
4040
aria-haspopup="menu"
4141
aria-expanded="false"
4242
variant="invisible"
43+
size="small"
4344
trailingAction={null}
4445
style={{display: 'inline-flex'}}
4546
{...rest}
@@ -80,13 +81,11 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
8081
const [menuItems, setMenuItems] = useState<React.ReactElement[]>([])
8182
const [itemWidths, setItemWidths] = useState<number[]>([])
8283
const [effectiveHideRoot, setEffectiveHideRoot] = useState<boolean>(hideRoot)
83-
const previousWidthsRef = useRef<string>('')
8484

8585
const childArray = React.Children.toArray(children).filter(child =>
8686
React.isValidElement(child),
8787
) as React.ReactElement[]
8888

89-
// Initialize visible items to show all items initially for measurement
9089
useEffect(() => {
9190
if (visibleItems.length === 0 && childArray.length > 0) {
9291
setVisibleItems(childArray)
@@ -101,26 +100,6 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
101100

102101
useResizeObserver(handleResize, containerRef)
103102

104-
// Calculate item widths from rendered items using parent container
105-
useEffect(() => {
106-
if (containerRef.current && overflow === 'menu') {
107-
const listElement = containerRef.current.querySelector('ol')
108-
if (listElement && listElement.children.length > 0) {
109-
// Only measure widths when all original items are visible (no overflow menu yet)
110-
if (listElement.children.length === childArray.length) {
111-
const widths = Array.from(listElement.children).map(child => (child as HTMLElement).offsetWidth)
112-
const widthsString = JSON.stringify(widths)
113-
// Only update if widths have actually changed to prevent infinite loops
114-
if (widthsString !== previousWidthsRef.current) {
115-
previousWidthsRef.current = widthsString
116-
setItemWidths(widths)
117-
}
118-
}
119-
}
120-
}
121-
}, [childArray, overflow, visibleItems])
122-
123-
// Calculate which items are visible vs in menu
124103
useEffect(() => {
125104
if (overflow === 'wrap') {
126105
setVisibleItems(childArray)
@@ -132,8 +111,22 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
132111
// For 'menu' overflow mode
133112
// Helper function to calculate visible items and menu items with progressive hiding
134113
const calculateOverflow = (availableWidth: number) => {
114+
const listElement = containerRef.current?.querySelector('ol')
115+
if (listElement && listElement.children.length > 0 && itemWidths.length === 0) {
116+
const widths = Array.from(listElement.children).map(child => (child as HTMLElement).offsetWidth)
117+
setItemWidths(widths)
118+
}
135119
const MENU_BUTTON_WIDTH = 50 // Approximate width of "..." button
136120

121+
// Helper function to calculate total width of visible items
122+
const calculateVisibleItemsWidth = (items: React.ReactElement[]) => {
123+
return items
124+
.map((item, index) => {
125+
return itemWidths[index]
126+
})
127+
.reduce((sum, width) => sum + width, 0)
128+
}
129+
137130
let currentVisibleItems = [...childArray]
138131
let currentMenuItems: React.ReactElement[] = []
139132

@@ -146,13 +139,8 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
146139
}
147140

148141
// Now check if current visible items fit in available width
149-
if (availableWidth > 0 && itemWidths.length === childArray.length) {
150-
let visibleItemsWidthTotal = currentVisibleItems
151-
.map(item => {
152-
const index = childArray.findIndex(child => child.key === item.key)
153-
return index !== -1 ? itemWidths[index] : 0
154-
})
155-
.reduce((sum, width) => sum + width, 0)
142+
if (availableWidth > 0) {
143+
let visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
156144

157145
// Add menu button width if we have hidden items
158146
if (currentMenuItems.length > 0) {
@@ -161,7 +149,6 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
161149

162150
// Progressive hiding: keep moving items to menu until they fit
163151
let effectiveHideRoot = hideRoot
164-
165152
while (visibleItemsWidthTotal > availableWidth && currentVisibleItems.length > 1) {
166153
// Determine which item to hide based on hideRoot setting
167154
let itemToHide: React.ReactElement
@@ -179,12 +166,7 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
179166
currentMenuItems = [itemToHide, ...currentMenuItems]
180167

181168
// Recalculate width
182-
visibleItemsWidthTotal = currentVisibleItems
183-
.map(item => {
184-
const index = childArray.findIndex(child => child.key === item.key)
185-
return index !== -1 ? itemWidths[index] : 0
186-
})
187-
.reduce((sum, width) => sum + width, 0)
169+
visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
188170

189171
// Add menu button width
190172
if (currentMenuItems.length > 0) {
@@ -206,24 +188,13 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
206188
currentMenuItems = [rootItem, ...currentMenuItems]
207189

208190
// Recalculate width one more time
209-
visibleItemsWidthTotal = currentVisibleItems
210-
.map(item => {
211-
const index = childArray.findIndex(child => child.key === item.key)
212-
return index !== -1 ? itemWidths[index] : 0
213-
})
214-
.reduce((sum, width) => sum + width, 0)
191+
visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
215192

216193
if (currentMenuItems.length > 0) {
217194
visibleItemsWidthTotal += MENU_BUTTON_WIDTH
218195
}
219196
}
220197
}
221-
222-
// Final check: if even the leaf breadcrumb + menu doesn't fit, just show them anyway
223-
// The CSS will handle truncation of the leaf breadcrumb
224-
if (visibleItemsWidthTotal > availableWidth && currentVisibleItems.length === 1) {
225-
// Keep the current configuration - CSS will handle truncation
226-
}
227198
}
228199

229200
return {

0 commit comments

Comments
 (0)