diff --git a/.changeset/witty-chicken-leave.md b/.changeset/witty-chicken-leave.md new file mode 100644 index 00000000000..e50471e3714 --- /dev/null +++ b/.changeset/witty-chicken-leave.md @@ -0,0 +1,5 @@ +--- +'@primer/react': major +--- + +Remove sx prop support from the SegmentedControl component. diff --git a/e2e/components/SegmentedControl.test.ts b/e2e/components/SegmentedControl.test.ts index 5247403ed1d..8ab6ba8b427 100644 --- a/e2e/components/SegmentedControl.test.ts +++ b/e2e/components/SegmentedControl.test.ts @@ -60,14 +60,6 @@ const stories = [ title: 'Dev: With Css', id: 'components-segmentedcontrol-dev--with-css', }, - { - title: 'Dev: With Sx', - id: 'components-segmentedcontrol-dev--with-sx', - }, - { - title: 'Dev: With Sx And Css', - id: 'components-segmentedcontrol-dev--with-sx-and-css', - }, ] as const test.describe('SegmentedControl', () => { diff --git a/packages/react/src/SegmentedControl/SegmentedControl.dev.stories.tsx b/packages/react/src/SegmentedControl/SegmentedControl.dev.stories.tsx index 3f44f7db7db..38519ec7f5a 100644 --- a/packages/react/src/SegmentedControl/SegmentedControl.dev.stories.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControl.dev.stories.tsx @@ -31,47 +31,3 @@ export const WithCss = () => ( ) - -export const WithSx = () => ( - - - Preview - - - Raw - - - Blame - - -) - -export const WithSxAndCss = () => ( - - - Preview - - - Raw - - - Blame - - -) diff --git a/packages/react/src/SegmentedControl/SegmentedControl.docs.json b/packages/react/src/SegmentedControl/SegmentedControl.docs.json index a4883889937..7c80557edee 100644 --- a/packages/react/src/SegmentedControl/SegmentedControl.docs.json +++ b/packages/react/src/SegmentedControl/SegmentedControl.docs.json @@ -78,12 +78,7 @@ "type": "'small' | 'medium'", "description": "The size of the buttons", "defaultValue": "" - }, - { - "name": "sx", - "type": "SystemStyleObject", - "deprecated": true - }, + }, { "name": "ref", "type": "React.RefObject" @@ -110,12 +105,7 @@ "type": "boolean", "defaultValue": "", "description": "Whether the segment is selected. This is used for uncontrolled SegmentedControls to pick one SegmentedControlButton that is selected on the initial render." - }, - { - "name": "sx", - "type": "SystemStyleObject", - "deprecated": true - }, + }, { "name": "ref", "type": "React.RefObject" @@ -156,12 +146,7 @@ "type": "boolean", "defaultValue": "", "description": "Whether the segment is selected. This is used for uncontrolled SegmentedControls to pick one SegmentedControlButton that is selected on the initial render." - }, - { - "name": "sx", - "type": "SystemStyleObject", - "deprecated": true - }, + }, { "name": "ref", "type": "React.RefObject" diff --git a/packages/react/src/SegmentedControl/SegmentedControl.tsx b/packages/react/src/SegmentedControl/SegmentedControl.tsx index 84946c4f518..f0e3ce38fd0 100644 --- a/packages/react/src/SegmentedControl/SegmentedControl.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControl.tsx @@ -6,18 +6,14 @@ import SegmentedControlIconButton from './SegmentedControlIconButton' import {ActionList} from '../ActionList' import {ActionMenu} from '../ActionMenu' import {useTheme} from '../ThemeProvider' -import type {SxProp} from '../sx' import type {ResponsiveValue} from '../hooks/useResponsiveValue' import {useResponsiveValue} from '../hooks/useResponsiveValue' import type {WidthOnlyViewportRangeKeys} from '../utils/types/ViewportRangeKeys' import {isElement} from 'react-is' - import classes from './SegmentedControl.module.css' - import {clsx} from 'clsx' -import {BoxWithFallback} from '../internal/components/BoxWithFallback' -type SegmentedControlProps = { +export type SegmentedControlProps = { 'aria-label'?: string 'aria-labelledby'?: string 'aria-describedby'?: string @@ -30,7 +26,7 @@ type SegmentedControlProps = { /** Configure alternative ways to render the control when it gets rendered in tight spaces */ variant?: 'default' | Partial> className?: string -} & SxProp +} const Root: React.FC> = ({ 'aria-label': ariaLabel, @@ -39,7 +35,6 @@ const Root: React.FC> = ({ fullWidth, onChange, size, - sx: sxProp, variant = 'default', className, ...rest @@ -153,9 +148,7 @@ const Root: React.FC> = ({ ) : ( // Render a segmented control - > = ({ index === selectedIndex || index === selectedIndex - 1 ? 'transparent' : theme?.colors.border.default, ...child.props.style, }, - sx: child.props.sx, } // Render the 'hideLabels' variant of the SegmentedControlButton @@ -201,7 +193,6 @@ const Root: React.FC> = ({ children: childPropsChildren, ...restChildProps } = child.props - const {sx: sharedSxProp, ...restSharedChildProps} = sharedChildProps if (!leadingIcon) { // eslint-disable-next-line no-console console.warn('A `leadingIcon` prop is required when hiding visible labels') @@ -210,14 +201,9 @@ const Root: React.FC> = ({ ) @@ -227,7 +213,7 @@ const Root: React.FC> = ({ // Render the children as-is and add the shared child props return React.cloneElement(child, sharedChildProps) })} - + ) } diff --git a/packages/react/src/SegmentedControl/SegmentedControlButton.tsx b/packages/react/src/SegmentedControl/SegmentedControlButton.tsx index cafd127ca20..3aa74f23312 100644 --- a/packages/react/src/SegmentedControl/SegmentedControlButton.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControlButton.tsx @@ -1,12 +1,10 @@ import type {ButtonHTMLAttributes} from 'react' import type React from 'react' import type {IconProps} from '@primer/octicons-react' -import type {SxProp} from '../sx' import {isElement} from 'react-is' import classes from './SegmentedControl.module.css' import {clsx} from 'clsx' -import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type SegmentedControlButtonProps = { /** The visible label rendered in the button */ @@ -17,28 +15,20 @@ export type SegmentedControlButtonProps = { defaultSelected?: boolean /** The leading icon comes before item label */ leadingIcon?: React.FunctionComponent> | React.ReactElement -} & SxProp & - ButtonHTMLAttributes +} & ButtonHTMLAttributes const SegmentedControlButton: React.FC> = ({ children, leadingIcon: LeadingIcon, selected, - sx: sxProp, className, // Note: this value is read in the `SegmentedControl` component to determine which button is selected but we do not need to apply it to an underlying element defaultSelected: _defaultSelected, ...rest }) => { return ( - - +
  • + +
  • ) } diff --git a/packages/react/src/SegmentedControl/SegmentedControlIconButton.tsx b/packages/react/src/SegmentedControl/SegmentedControlIconButton.tsx index 399f67be575..446ebc4d4ee 100644 --- a/packages/react/src/SegmentedControl/SegmentedControlIconButton.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControlIconButton.tsx @@ -1,14 +1,12 @@ import type {ButtonHTMLAttributes} from 'react' 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' import {Tooltip} from '../TooltipV2' -import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type SegmentedControlIconButtonProps = { 'aria-label': string @@ -22,14 +20,12 @@ export type SegmentedControlIconButtonProps = { description?: string /** The direction for the tooltip.*/ tooltipDirection?: TooltipDirection -} & SxProp & - ButtonHTMLAttributes +} & ButtonHTMLAttributes export const SegmentedControlIconButton: React.FC> = ({ 'aria-label': ariaLabel, icon: Icon, selected, - sx: sxProp, className, description, tooltipDirection, @@ -38,19 +34,14 @@ export const SegmentedControlIconButton: React.FC +
  • - {isElement(Icon) ? Icon : } - + - +
  • ) } else { // This can be removed when primer_react_segmented_control_tooltip feature flag is GA-ed. return ( - - + + ) } } diff --git a/packages/react/src/SegmentedControl/index.ts b/packages/react/src/SegmentedControl/index.ts index 44bd6215d6b..abb2932cb5e 100644 --- a/packages/react/src/SegmentedControl/index.ts +++ b/packages/react/src/SegmentedControl/index.ts @@ -1 +1,5 @@ export * from './SegmentedControl' + +export type {SegmentedControlProps} from './SegmentedControl' +export type {SegmentedControlButtonProps} from './SegmentedControlButton' +export type {SegmentedControlIconButtonProps} from './SegmentedControlIconButton' diff --git a/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap index 0c462053e33..7570eb50cdd 100644 --- a/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap +++ b/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap @@ -130,6 +130,9 @@ exports[`@primer/react > should not update exports without a semver change 1`] = "type RelativeTimeProps", "ResponsiveValue", "SegmentedControl", + "type SegmentedControlButtonProps", + "type SegmentedControlIconButtonProps", + "type SegmentedControlProps", "Select", "SelectPanel", "type SelectPanelGroupedListProps", diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 2d2c5365d04..ad864dc1983 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -134,6 +134,11 @@ export {default as RadioGroup} from './RadioGroup' export type {RelativeTimeProps} from './RelativeTime' export {default as RelativeTime} from './RelativeTime' export {SegmentedControl} from './SegmentedControl' +export type { + SegmentedControlProps, + SegmentedControlButtonProps, + SegmentedControlIconButtonProps, +} from './SegmentedControl' // Curently there is a duplicate Select component at the root of the dir, so need to be explicit about exporting from the src/Select dir export {default as Select} from './Select' export type {SelectProps} from './Select' diff --git a/packages/styled-react/src/__tests__/primer-react.browser.test.tsx b/packages/styled-react/src/__tests__/primer-react.browser.test.tsx index 7909455e5ae..f0340084e04 100644 --- a/packages/styled-react/src/__tests__/primer-react.browser.test.tsx +++ b/packages/styled-react/src/__tests__/primer-react.browser.test.tsx @@ -328,12 +328,30 @@ describe('@primer/react', () => { expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') }) + test('SegmentedControl supports `sx` prop', () => { + render() + expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') + }) + test('SegmentedControl.Button supports `sx` prop', () => { - const {container} = render( + render( test , ) + const buttonElement = screen.getByTestId('component') + expect(window.getComputedStyle(buttonElement).backgroundColor).toBe('rgb(255, 0, 0)') + }) + + test('SegmentedControl.IconButton supports `sx` prop', () => { + const {container} = render( + } + />, + ) expect(window.getComputedStyle(container.firstElementChild!).backgroundColor).toBe('rgb(255, 0, 0)') }) diff --git a/packages/styled-react/src/index.tsx b/packages/styled-react/src/index.tsx index bb1405345f0..953d20b1d75 100644 --- a/packages/styled-react/src/index.tsx +++ b/packages/styled-react/src/index.tsx @@ -10,8 +10,12 @@ import { type SubNavLinkProps as PrimerSubNavLinkProps, ToggleSwitch as PrimerToggleSwitch, type ToggleSwitchProps as PrimerToggleSwitchProps, + type SegmentedControlProps as PrimerSegmentedControlProps, + SegmentedControl as PrimerSegmentedControl, + type SegmentedControlButtonProps as PrimerSegmentedControlButtonProps, + type SegmentedControlIconButtonProps as PrimerSegmentedControlIconButtonProps, } from '@primer/react' -import {forwardRef} from 'react' +import React, {forwardRef, type PropsWithChildren} from 'react' import type { BackgroundProps, BorderProps, @@ -37,6 +41,27 @@ type StyledProps = SxProp & PositionProps & ShadowProps +type SegmentedControlProps = PropsWithChildren & SxProp +type SegmentedControlButtonProps = PropsWithChildren & SxProp +type SegmentedControlIconButtonProps = PropsWithChildren & SxProp + +const SegmentedControlButton = (props: SegmentedControlButtonProps) => { + return +} + +const SegmentedControlIconButton = (props: SegmentedControlIconButtonProps) => { + return +} + +const SegmentedControlImpl = (props: SegmentedControlProps) => { + return +} + +const SegmentedControl = Object.assign(SegmentedControlImpl, { + Button: SegmentedControlButton, + IconButton: SegmentedControlIconButton, +}) + type StateLabelProps = PrimerStateLabelProps & SxProp const StateLabel = forwardRef(function StateLabel(props, ref) { @@ -65,7 +90,7 @@ const ToggleSwitch = forwardRef(function T return }) -export {StateLabel, SubNav, ToggleSwitch} +export {SegmentedControl, StateLabel, SubNav, ToggleSwitch} export { ActionList, @@ -96,7 +121,6 @@ export { ProgressBar, RadioGroup, RelativeTime, - SegmentedControl, Select, Spinner, Text,