Skip to content

Clean up the feature flag for primer_react_segmented_control_tooltip #6307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions .changeset/strong-mangos-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

Remove the feature flag for `primer_react_segmented_control_tooltip` and GA tootip by default behavior.
1 change: 0 additions & 1 deletion packages/react/src/FeatureFlags/DefaultFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export const DefaultFeatureFlags = FeatureFlagScope.create({
primer_react_action_list_item_as_button: false,
primer_react_select_panel_with_modern_action_list: false,
primer_react_overlay_overflow: false,
primer_react_segmented_control_tooltip: false,
primer_react_select_panel_fullscreen_on_narrow: false,
primer_react_select_panel_order_selected_at_top: false,
})
52 changes: 12 additions & 40 deletions packages/react/src/SegmentedControl/SegmentedControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {describe, expect, it, vi} from 'vitest'
import BaseStyles from '../BaseStyles'
import theme from '../theme'
import ThemeProvider from '../ThemeProvider'
import {FeatureFlags} from '../FeatureFlags'
import {SegmentedControl} from '../SegmentedControl'

const segmentData = [
Expand Down Expand Up @@ -144,19 +143,13 @@ describe('SegmentedControl', () => {
}
})

it('renders icon button with tooltip as label when feature flag is enabled', () => {
it('renders icon button with tooltip as label', () => {
const {getByRole, getByText} = render(
<FeatureFlags
flags={{
primer_react_segmented_control_tooltip: true,
}}
>
<SegmentedControl aria-label="File view">
{segmentData.map(({label, icon}) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} key={label} />
))}
</SegmentedControl>
</FeatureFlags>,
<SegmentedControl aria-label="File view">
{segmentData.map(({label, icon}) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} key={label} />
))}
</SegmentedControl>,
)

for (const datum of segmentData) {
Expand All @@ -167,41 +160,20 @@ describe('SegmentedControl', () => {
}
})

it('renders icon button with tooltip description when feature flag is enabled', () => {
it('renders icon button with tooltip description', () => {
const {getByRole, getByText} = render(
<FeatureFlags
flags={{
primer_react_segmented_control_tooltip: true,
}}
>
<SegmentedControl aria-label="File view">
{segmentData.map(({label, icon, description}) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} description={description} key={label} />
))}
</SegmentedControl>
</FeatureFlags>,
)

for (const datum of segmentData) {
const labelledButton = getByRole('button', {name: datum.label})
const tooltipElement = getByText(datum.description)
expect(labelledButton).toHaveAttribute('aria-describedby', tooltipElement.id)
expect(labelledButton).toHaveAccessibleName(datum.label)
expect(labelledButton).toHaveAttribute('aria-label', datum.label)
}
})

it('renders icon button with aria-label and no tooltip', () => {
const {getByRole} = render(
<SegmentedControl aria-label="File view">
{segmentData.map(({label, icon}) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} key={label} />
{segmentData.map(({label, icon, description}) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} description={description} key={label} />
))}
</SegmentedControl>,
)

for (const datum of segmentData) {
const labelledButton = getByRole('button', {name: datum.label})
const tooltipElement = getByText(datum.description)
expect(labelledButton).toHaveAttribute('aria-describedby', tooltipElement.id)
expect(labelledButton).toHaveAccessibleName(datum.label)
expect(labelledButton).toHaveAttribute('aria-label', datum.label)
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type React from 'react'
import type {IconProps} from '@primer/octicons-react'
import type {SxProp} from '../sx'
import {isElement} from 'react-is'
import {useFeatureFlag} from '../FeatureFlags'
import type {TooltipDirection} from '../TooltipV2'
import classes from './SegmentedControl.module.css'
import {clsx} from 'clsx'
Expand Down Expand Up @@ -35,56 +34,31 @@ export const SegmentedControlIconButton: React.FC<React.PropsWithChildren<Segmen
tooltipDirection,
...rest
}) => {
const tooltipFlagEnabled = useFeatureFlag('primer_react_segmented_control_tooltip')
if (tooltipFlagEnabled) {
return (
<BoxWithFallback
as="li"
sx={sxProp}
className={clsx(classes.Item, className)}
data-selected={selected || undefined}
>
<Tooltip
type={description ? undefined : 'label'}
text={description ? description : ariaLabel}
direction={tooltipDirection}
>
<BoxWithFallback
as="button"
aria-current={selected}
// If description is provided, we will use the tooltip to describe the button, so we need to keep the aria-label to label the button.
aria-label={description ? ariaLabel : undefined}
className={clsx(classes.Button, classes.IconButton)}
{...rest}
>
<span className={clsx(classes.Content, 'segmentedControl-content')}>
{isElement(Icon) ? Icon : <Icon />}
</span>
</BoxWithFallback>
</Tooltip>
</BoxWithFallback>
)
} else {
// This can be removed when primer_react_segmented_control_tooltip feature flag is GA-ed.
return (
<BoxWithFallback
as="li"
sx={sxProp}
className={clsx(classes.Item, className)}
data-selected={selected || undefined}
return (
<BoxWithFallback
as="li"
sx={sxProp}
className={clsx(classes.Item, className)}
data-selected={selected || undefined}
>
<Tooltip
type={description ? undefined : 'label'}
text={description ? description : ariaLabel}
direction={tooltipDirection}
>
<BoxWithFallback
as="button"
aria-label={ariaLabel}
aria-current={selected}
// If description is provided, we will use the tooltip to describe the button, so we need to keep the aria-label to label the button.
aria-label={description ? ariaLabel : undefined}
className={clsx(classes.Button, classes.IconButton)}
{...rest}
>
<span className={clsx(classes.Content, 'segmentedControl-content')}>{isElement(Icon) ? Icon : <Icon />}</span>
</BoxWithFallback>
</BoxWithFallback>
)
}
</Tooltip>
</BoxWithFallback>
)
}

export default SegmentedControlIconButton
Loading