diff --git a/.changeset/proud-timers-grow.md b/.changeset/proud-timers-grow.md
new file mode 100644
index 00000000000..d8661fac52a
--- /dev/null
+++ b/.changeset/proud-timers-grow.md
@@ -0,0 +1,6 @@
+---
+"@primer/react": patch
+---
+
+Breadcrumbs: Remove feature flag for overflow_menu, this behavior is now the default
+
diff --git a/packages/react/src/Breadcrumbs/Breadcrumbs.features.stories.tsx b/packages/react/src/Breadcrumbs/Breadcrumbs.features.stories.tsx
index 1e8d695d3a4..b33efcbc5dd 100644
--- a/packages/react/src/Breadcrumbs/Breadcrumbs.features.stories.tsx
+++ b/packages/react/src/Breadcrumbs/Breadcrumbs.features.stories.tsx
@@ -2,7 +2,6 @@ import type {Meta} from '@storybook/react-vite'
import type React from 'react'
import type {ComponentProps} from '../utils/types'
import Breadcrumbs from './Breadcrumbs'
-import {FeatureFlags} from '../FeatureFlags'
export default {
title: 'Components/Breadcrumbs/Features',
@@ -23,23 +22,7 @@ export const OverflowWrap = () => (
)
-export const OverflowMenuFeatureFlagEnabled = () => (
-
-
- Home
- Products
- Category
- Subcategory
- Item
- Details
-
- Current Page
-
-
-
-)
-
-export const OverflowMenuFeatureFlagDisabled = () => (
+export const OverflowMenu = () => (
Home
Products
@@ -53,7 +36,7 @@ export const OverflowMenuFeatureFlagDisabled = () => (
)
-export const OverflowMenuShowRootFeatureFlagDisabled = () => (
+export const OverflowMenuShowRoot = () => (
github
Teams
@@ -66,35 +49,18 @@ export const OverflowMenuShowRootFeatureFlagDisabled = () => (
)
-export const OverflowMenuShowRootFeatureFlagEnabled = () => (
-
-
- github
- Teams
- Engineering
- core-productivity
- collaboration-workflows-flex
-
- global-navigation-reviewers
-
-
-
-)
-
export const SpaciousVariantWithOverflowMenu = () => (
-
-
- Home
- Products
- Category
- Subcategory
- Item
- Details
-
- Current Page
-
-
-
+
+ Home
+ Products
+ Category
+ Subcategory
+ Item
+ Details
+
+ Current Page
+
+
)
export const SpaciousVariantWithOverflowWrap = () => (
diff --git a/packages/react/src/Breadcrumbs/Breadcrumbs.tsx b/packages/react/src/Breadcrumbs/Breadcrumbs.tsx
index 6e69095ca79..b773b1f9596 100644
--- a/packages/react/src/Breadcrumbs/Breadcrumbs.tsx
+++ b/packages/react/src/Breadcrumbs/Breadcrumbs.tsx
@@ -10,7 +10,6 @@ import {useResizeObserver} from '../hooks/useResizeObserver'
import type {ResizeObserverEntry} from '../hooks/useResizeObserver'
import {useOnEscapePress} from '../hooks/useOnEscapePress'
import {useOnOutsideClick} from '../hooks/useOnOutsideClick'
-import {useFeatureFlag} from '../FeatureFlags'
export type BreadcrumbsProps = React.PropsWithChildren<{
/**
@@ -145,8 +144,6 @@ const getValidChildren = (children: React.ReactNode) => {
}
function Breadcrumbs({className, children, style, overflow = 'wrap', variant = 'normal'}: BreadcrumbsProps) {
- const overflowMenuEnabled = useFeatureFlag('primer_react_breadcrumbs_overflow_menu')
- const wrappedChildren = React.Children.map(children, child =>
{child} )
const containerRef = useRef(null)
const measureMenuButton = useCallback((element: HTMLDetailsElement | null) => {
@@ -176,18 +173,13 @@ function Breadcrumbs({className, children, style, overflow = 'wrap', variant = '
useEffect(() => {
const listElement = containerRef.current?.querySelector('ol')
- if (
- overflowMenuEnabled &&
- listElement &&
- listElement.children.length > 0 &&
- listElement.children.length === childArray.length
- ) {
+ if (listElement && listElement.children.length > 0 && listElement.children.length === childArray.length) {
const listElementArray = Array.from(listElement.children) as HTMLElement[]
const widths = listElementArray.map(child => child.offsetWidth)
setChildArrayWidths(widths)
setRootItemWidth(listElementArray[0].offsetWidth)
}
- }, [childArray, overflowMenuEnabled])
+ }, [childArray])
const calculateOverflow = useCallback(
(availableWidth: number) => {
@@ -247,7 +239,7 @@ function Breadcrumbs({className, children, style, overflow = 'wrap', variant = '
const handleResize = useCallback(
(entries: ResizeObserverEntry[]) => {
- if (overflowMenuEnabled && entries[0]) {
+ if (entries[0]) {
const containerWidth = entries[0].contentRect.width
const result = calculateOverflow(containerWidth)
if (
@@ -260,73 +252,66 @@ function Breadcrumbs({className, children, style, overflow = 'wrap', variant = '
}
}
},
- [calculateOverflow, effectiveHideRoot, menuItems.length, overflowMenuEnabled, visibleItems.length],
+ [calculateOverflow, effectiveHideRoot, menuItems.length, visibleItems.length],
)
useResizeObserver(handleResize, containerRef)
useEffect(() => {
- if (
- overflowMenuEnabled &&
- (overflow === 'menu' || overflow === 'menu-with-root') &&
- childArray.length > 5 &&
- menuItems.length === 0
- ) {
+ if ((overflow === 'menu' || overflow === 'menu-with-root') && childArray.length > 5 && menuItems.length === 0) {
const containerWidth = containerRef.current?.offsetWidth || 800
const result = calculateOverflow(containerWidth)
setVisibleItems(result.visibleItems)
setMenuItems(result.menuItems)
setEffectiveHideRoot(result.effectiveHideRoot)
}
- }, [overflow, childArray, calculateOverflow, menuItems.length, overflowMenuEnabled])
+ }, [overflow, childArray, calculateOverflow, menuItems.length])
const finalChildren = React.useMemo(() => {
- if (overflowMenuEnabled) {
- if (overflow === 'wrap' || menuItems.length === 0) {
- return React.Children.map(children, child => {child} )
- }
+ if (overflow === 'wrap' || menuItems.length === 0) {
+ return React.Children.map(children, child => {child} )
+ }
- let effectiveMenuItems = [...menuItems]
- // In 'menu-with-root' mode, include the root item inside the menu even if it's visible in the breadcrumbs
- if (!effectiveHideRoot) {
- effectiveMenuItems = [...menuItems.slice(1)]
- }
- const menuElement = (
-
-
-
-
- )
-
- const visibleElements = visibleItems.map((child, index) => (
-
- {child}
-
-
- ))
-
- const rootElement = (
-
- {rootItem}
-
-
- )
-
- if (effectiveHideRoot) {
- // Show: [overflow menu, leaf breadcrumb]
- return [menuElement, ...visibleElements]
- } else {
- // Show: [root breadcrumb, overflow menu, leaf breadcrumb]
- return [rootElement, menuElement, ...visibleElements]
- }
+ let effectiveMenuItems = [...menuItems]
+ // In 'menu-with-root' mode, include the root item inside the menu even if it's visible in the breadcrumbs
+ if (!effectiveHideRoot) {
+ effectiveMenuItems = [...menuItems.slice(1)]
+ }
+ const menuElement = (
+
+
+
+
+ )
+
+ const visibleElements = visibleItems.map((child, index) => (
+
+ {child}
+
+
+ ))
+
+ const rootElement = (
+
+ {rootItem}
+
+
+ )
+
+ if (effectiveHideRoot) {
+ // Show: [overflow menu, leaf breadcrumb]
+ return [menuElement, ...visibleElements]
+ } else {
+ // Show: [root breadcrumb, overflow menu, leaf breadcrumb]
+ return [rootElement, menuElement, ...visibleElements]
}
- }, [overflowMenuEnabled, overflow, menuItems, effectiveHideRoot, measureMenuButton, visibleItems, rootItem, children])
+ }, [overflow, menuItems, effectiveHideRoot, measureMenuButton, visibleItems, rootItem, children])
- return overflowMenuEnabled ? (
+ return (
) => {
- const wrappedComponent = flags ? {component} : <>{component}>
- return HTMLRender(wrappedComponent)
-}
// Mock ResizeObserver for tests
const mockObserve = vi.fn()
@@ -57,30 +50,28 @@ describe('Breadcrumbs', () => {
expect(selectedItem).toHaveAttribute('aria-current', 'page')
})
- it('sets data-overflow attribute when overflow is menu with feature flag', () => {
- const {container} = renderWithTheme(
+ it('sets data-overflow attribute when overflow is menu', () => {
+ const {container} = HTMLRender(
Home
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(container.firstChild).toHaveAttribute('data-overflow', 'menu')
})
it('sets data-overflow attribute when overflow is wrap', () => {
- const {container} = renderWithTheme(
+ const {container} = HTMLRender(
Home
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(container.firstChild).toHaveAttribute('data-overflow', 'wrap')
})
it('renders all items when overflow is wrap', () => {
- renderWithTheme(
+ HTMLRender(
Item 1
Item 2
@@ -89,7 +80,6 @@ describe('Breadcrumbs', () => {
Item 5
Item 6
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// All items should be visible in wrap mode
@@ -102,7 +92,7 @@ describe('Breadcrumbs', () => {
})
it('shows overflow menu when more than 5 items in menu mode', () => {
- renderWithTheme(
+ HTMLRender(
Item 1
Item 2
@@ -111,7 +101,6 @@ describe('Breadcrumbs', () => {
Item 5
Item 6
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// Should have overflow menu button
@@ -126,12 +115,11 @@ describe('Breadcrumbs', () => {
it('show root in menu', () => {
expect(() => {
- renderWithTheme(
+ HTMLRender(
Home
Docs
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
}).not.toThrow()
})
@@ -139,7 +127,7 @@ describe('Breadcrumbs', () => {
it('includes root item in overflow menu when overflow is menu-with-root', async () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Home
Category
@@ -151,7 +139,6 @@ describe('Breadcrumbs', () => {
Reviews
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// Should have overflow menu button
@@ -186,7 +173,7 @@ describe('Breadcrumbs', () => {
})
it('renders accessible overflow menu', () => {
- renderWithTheme(
+ HTMLRender(
Item 1
Item 2
@@ -195,7 +182,6 @@ describe('Breadcrumbs', () => {
Item 5
Item 6
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
const menuButton = screen.getByRole('button', {name: /more breadcrumb items/i})
@@ -215,7 +201,7 @@ describe('Breadcrumbs', () => {
})
globalThis.ResizeObserver = mockResizeObserver
- renderWithTheme(
+ HTMLRender(
Item 1
Item 2
@@ -224,7 +210,6 @@ describe('Breadcrumbs', () => {
Item 5
Item 6
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(resizeCallback).toBeDefined()
@@ -275,7 +260,7 @@ describe('Breadcrumbs', () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Home
Category
@@ -285,7 +270,6 @@ describe('Breadcrumbs', () => {
Specifications
Reviews
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(resizeCallback).toBeDefined()
@@ -361,7 +345,7 @@ describe('Breadcrumbs', () => {
it('closes menu on Escape key press', async () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Home
Docs
@@ -372,7 +356,6 @@ describe('Breadcrumbs', () => {
Advanced
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// Open the overflow menu
@@ -398,7 +381,7 @@ describe('Breadcrumbs', () => {
it('closes menu when clicking outside', async () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Outside Button
@@ -414,7 +397,6 @@ describe('Breadcrumbs', () => {
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// Open the overflow menu
@@ -439,7 +421,7 @@ describe('Breadcrumbs', () => {
it('allows tab navigation through menu items', async () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Home
Docs
@@ -450,7 +432,6 @@ describe('Breadcrumbs', () => {
Advanced
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
// Open the overflow menu
@@ -479,7 +460,7 @@ describe('Breadcrumbs', () => {
it('maintains focus on menu button when menu is closed', async () => {
const user = userEvent.setup()
- renderWithTheme(
+ HTMLRender(
Home
Docs
@@ -490,7 +471,6 @@ describe('Breadcrumbs', () => {
Advanced
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
const menuButton = screen.getByRole('button', {name: /more breadcrumb items/i})
@@ -517,27 +497,25 @@ describe('Breadcrumbs', () => {
describe('variant prop (feature flag on)', () => {
it('sets data-variant="normal" by default', () => {
- const {container} = renderWithTheme(
+ const {container} = HTMLRender(
Home
Docs
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(container.firstChild).toHaveAttribute('data-variant', 'normal')
})
it('sets data-variant="spacious" when variant prop provided', () => {
- const {container} = renderWithTheme(
+ const {container} = HTMLRender(
Home
Docs
,
- {primer_react_breadcrumbs_overflow_menu: true},
)
expect(container.firstChild).toHaveAttribute('data-variant', 'spacious')
})
diff --git a/packages/react/src/FeatureFlags/DefaultFeatureFlags.ts b/packages/react/src/FeatureFlags/DefaultFeatureFlags.ts
index 7a1112d7e37..7a47ff3e7ba 100644
--- a/packages/react/src/FeatureFlags/DefaultFeatureFlags.ts
+++ b/packages/react/src/FeatureFlags/DefaultFeatureFlags.ts
@@ -2,7 +2,6 @@ import {FeatureFlagScope} from './FeatureFlagScope'
export const DefaultFeatureFlags = FeatureFlagScope.create({
primer_react_action_list_item_as_button: false,
- primer_react_breadcrumbs_overflow_menu: false,
primer_react_overlay_overflow: false,
primer_react_segmented_control_tooltip: false,
primer_react_select_panel_fullscreen_on_narrow: false,