Skip to content

Commit d42ac5e

Browse files
committed
check for zero children
1 parent dffe0f1 commit d42ac5e

File tree

1 file changed

+89
-87
lines changed

1 file changed

+89
-87
lines changed

packages/react/src/Breadcrumbs/Breadcrumbs.tsx

Lines changed: 89 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -101,114 +101,116 @@ function Breadcrumbs({className, children, sx: sxProp, overflow = 'wrap', hideRo
101101
useResizeObserver(handleResize, containerRef)
102102

103103
useEffect(() => {
104-
if (overflow === 'wrap') {
105-
setVisibleItems(childArray)
106-
setMenuItems([])
107-
setEffectiveHideRoot(hideRoot)
108-
return
109-
}
110-
111-
// For 'menu' overflow mode
112-
// Helper function to calculate visible items and menu items with progressive hiding
113-
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-
}
119-
const MENU_BUTTON_WIDTH = 50 // Approximate width of "..." button
120-
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-
130-
let currentVisibleItems = [...childArray]
131-
let currentMenuItems: React.ReactElement[] = []
132-
133-
// If more than 5 items, start by reducing to 5 visible items (including menu)
134-
if (childArray.length > 5) {
135-
// Target: 4 visible items + 1 menu = 5 total
136-
const itemsToHide = childArray.slice(0, childArray.length - 4)
137-
currentMenuItems = itemsToHide
138-
currentVisibleItems = childArray.slice(childArray.length - 4)
104+
if (childArray.length > 0) {
105+
if (overflow === 'wrap') {
106+
setVisibleItems(childArray)
107+
setMenuItems([])
108+
setEffectiveHideRoot(hideRoot)
109+
return
139110
}
140111

141-
// Now check if current visible items fit in available width
142-
if (availableWidth > 0) {
143-
let visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
144-
145-
// Add menu button width if we have hidden items
146-
if (currentMenuItems.length > 0) {
147-
visibleItemsWidthTotal += MENU_BUTTON_WIDTH
112+
// For 'menu' overflow mode
113+
// Helper function to calculate visible items and menu items with progressive hiding
114+
const calculateOverflow = (availableWidth: number) => {
115+
const listElement = containerRef.current?.querySelector('ol')
116+
if (listElement && listElement.children.length > 0 && itemWidths.length === 0) {
117+
const widths = Array.from(listElement.children).map(child => (child as HTMLElement).offsetWidth)
118+
setItemWidths(widths)
119+
}
120+
const MENU_BUTTON_WIDTH = 50 // Approximate width of "..." button
121+
122+
// Helper function to calculate total width of visible items
123+
const calculateVisibleItemsWidth = (items: React.ReactElement[]) => {
124+
return items
125+
.map((item, index) => {
126+
return itemWidths[index]
127+
})
128+
.reduce((sum, width) => sum + width, 0)
148129
}
149130

150-
// Progressive hiding: keep moving items to menu until they fit
151-
let effectiveHideRoot = hideRoot
152-
while (visibleItemsWidthTotal > availableWidth && currentVisibleItems.length > 1) {
153-
// Determine which item to hide based on hideRoot setting
154-
let itemToHide: React.ReactElement
155-
156-
if (effectiveHideRoot) {
157-
// Hide from start when hideRoot is true
158-
itemToHide = currentVisibleItems[0]
159-
currentVisibleItems = currentVisibleItems.slice(1)
160-
} else {
161-
// Try to hide second item (keep root and leaf) when hideRoot is false
162-
itemToHide = currentVisibleItems[1]
163-
currentVisibleItems = [currentVisibleItems[0], ...currentVisibleItems.slice(2)]
164-
}
131+
let currentVisibleItems = [...childArray]
132+
let currentMenuItems: React.ReactElement[] = []
165133

166-
currentMenuItems = [itemToHide, ...currentMenuItems]
134+
// If more than 5 items, start by reducing to 5 visible items (including menu)
135+
if (childArray.length > 5) {
136+
// Target: 4 visible items + 1 menu = 5 total
137+
const itemsToHide = childArray.slice(0, childArray.length - 4)
138+
currentMenuItems = itemsToHide
139+
currentVisibleItems = childArray.slice(childArray.length - 4)
140+
}
167141

168-
// Recalculate width
169-
visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
142+
// Now check if current visible items fit in available width
143+
if (availableWidth > 0) {
144+
let visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
170145

171-
// Add menu button width
146+
// Add menu button width if we have hidden items
172147
if (currentMenuItems.length > 0) {
173148
visibleItemsWidthTotal += MENU_BUTTON_WIDTH
174149
}
175150

176-
// If hideRoot is false but we still don't fit with root + menu + leaf,
177-
// fallback to hideRoot=true behavior (menu + leaf only)
178-
if (
179-
!hideRoot &&
180-
!effectiveHideRoot &&
181-
currentVisibleItems.length === 2 &&
182-
visibleItemsWidthTotal > availableWidth
183-
) {
184-
effectiveHideRoot = true
185-
// Move the root item to menu as well
186-
const rootItem = currentVisibleItems[0]
187-
currentVisibleItems = currentVisibleItems.slice(1)
188-
currentMenuItems = [rootItem, ...currentMenuItems]
189-
190-
// Recalculate width one more time
151+
// Progressive hiding: keep moving items to menu until they fit
152+
let effectiveHideRoot = hideRoot
153+
while (visibleItemsWidthTotal > availableWidth && currentVisibleItems.length > 1) {
154+
// Determine which item to hide based on hideRoot setting
155+
let itemToHide: React.ReactElement
156+
157+
if (effectiveHideRoot) {
158+
// Hide from start when hideRoot is true
159+
itemToHide = currentVisibleItems[0]
160+
currentVisibleItems = currentVisibleItems.slice(1)
161+
} else {
162+
// Try to hide second item (keep root and leaf) when hideRoot is false
163+
itemToHide = currentVisibleItems[1]
164+
currentVisibleItems = [currentVisibleItems[0], ...currentVisibleItems.slice(2)]
165+
}
166+
167+
currentMenuItems = [itemToHide, ...currentMenuItems]
168+
169+
// Recalculate width
191170
visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
192171

172+
// Add menu button width
193173
if (currentMenuItems.length > 0) {
194174
visibleItemsWidthTotal += MENU_BUTTON_WIDTH
195175
}
176+
177+
// If hideRoot is false but we still don't fit with root + menu + leaf,
178+
// fallback to hideRoot=true behavior (menu + leaf only)
179+
if (
180+
!hideRoot &&
181+
!effectiveHideRoot &&
182+
currentVisibleItems.length === 2 &&
183+
visibleItemsWidthTotal > availableWidth
184+
) {
185+
effectiveHideRoot = true
186+
// Move the root item to menu as well
187+
const rootItem = currentVisibleItems[0]
188+
currentVisibleItems = currentVisibleItems.slice(1)
189+
currentMenuItems = [rootItem, ...currentMenuItems]
190+
191+
// Recalculate width one more time
192+
visibleItemsWidthTotal = calculateVisibleItemsWidth(currentVisibleItems)
193+
194+
if (currentMenuItems.length > 0) {
195+
visibleItemsWidthTotal += MENU_BUTTON_WIDTH
196+
}
197+
}
196198
}
197199
}
198-
}
199200

200-
return {
201-
visibleItems: currentVisibleItems,
202-
menuItems: currentMenuItems,
203-
effectiveHideRoot,
201+
return {
202+
visibleItems: currentVisibleItems,
203+
menuItems: currentMenuItems,
204+
effectiveHideRoot,
205+
}
204206
}
205-
}
206207

207-
// Apply the overflow calculation
208-
const result = calculateOverflow(containerWidth)
209-
setVisibleItems(result.visibleItems)
210-
setMenuItems(result.menuItems)
211-
setEffectiveHideRoot(result.effectiveHideRoot)
208+
// Apply the overflow calculation
209+
const result = calculateOverflow(containerWidth)
210+
setVisibleItems(result.visibleItems)
211+
setMenuItems(result.menuItems)
212+
setEffectiveHideRoot(result.effectiveHideRoot)
213+
}
212214
}, [childArray, overflow, containerWidth, hideRoot, itemWidths, effectiveHideRoot])
213215

214216
// Determine final children to render

0 commit comments

Comments
 (0)