From 6a86e54562e9101fcb82b3bbdc9496f499df1211 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Tue, 30 Sep 2025 17:13:34 -0400 Subject: [PATCH 01/17] rms BoxWithFallback and sx prop from InputLabel and UnstyledTextInput --- .../src/internal/components/InputLabel.tsx | 53 ++++++++----------- .../internal/components/UnstyledTextInput.tsx | 6 +-- 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/packages/react/src/internal/components/InputLabel.tsx b/packages/react/src/internal/components/InputLabel.tsx index 63e7bf86086..b1314bfcfb8 100644 --- a/packages/react/src/internal/components/InputLabel.tsx +++ b/packages/react/src/internal/components/InputLabel.tsx @@ -1,32 +1,26 @@ import {clsx} from 'clsx' import type React from 'react' -import {type SxProp} from '../../sx' +import type {ElementType} from 'react' import classes from './InputLabel.module.css' -import {BoxWithFallback} from './BoxWithFallback' +import type {PolymorphicProps} from '../../utils/modern-polymorphic' -type BaseProps = SxProp & { - disabled?: boolean - required?: boolean - requiredText?: string - requiredIndicator?: boolean - visuallyHidden?: boolean - id?: string - className?: string -} - -export type LabelProps = BaseProps & { - htmlFor?: string - as?: 'label' -} - -export type LegendOrSpanProps = BaseProps & { - as: 'legend' | 'span' - htmlFor?: undefined -} +type InputLabelProps = PolymorphicProps< + As, + 'label', + { + disabled?: boolean + required?: boolean + requiredText?: string + requiredIndicator?: boolean + visuallyHidden?: boolean + } +> & + React.PropsWithChildren -type Props = React.PropsWithChildren +export type LabelProps = InputLabelProps<'label'> +export type LegendOrSpanProps = InputLabelProps<'legend' | 'span'> -function InputLabel({ +function InputLabel({ children, disabled, htmlFor, @@ -35,16 +29,13 @@ function InputLabel({ requiredText, requiredIndicator, visuallyHidden, - sx, - as = 'label', + as, className, ...props -}: Props) { +}: InputLabelProps) { + const Component = as || 'label' return ( - // @ts-ignore weird typing issue with union for `as` prop - + ) } diff --git a/packages/react/src/internal/components/UnstyledTextInput.tsx b/packages/react/src/internal/components/UnstyledTextInput.tsx index a86e9db9aac..bb419f84f71 100644 --- a/packages/react/src/internal/components/UnstyledTextInput.tsx +++ b/packages/react/src/internal/components/UnstyledTextInput.tsx @@ -1,17 +1,15 @@ -import {type SxProp} from '../../sx' import React from 'react' import styles from './UnstyledTextInput.module.css' import {clsx} from 'clsx' -import {BoxWithFallback} from './BoxWithFallback' -type ToggledUnstyledTextInputProps = React.ComponentPropsWithoutRef<'input'> & SxProp +type ToggledUnstyledTextInputProps = React.ComponentPropsWithoutRef<'input'> const UnstyledTextInput = React.forwardRef(function UnstyledTextInput( {className, ...rest}, forwardRef, ) { - return + return }) UnstyledTextInput.displayName = 'UnstyledTextInput' From 0787f121f8d72cbd05ecc0a86206a02dd01095d0 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Tue, 30 Sep 2025 17:17:46 -0400 Subject: [PATCH 02/17] adds changeset --- .changeset/better-steaks-dress.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/better-steaks-dress.md diff --git a/.changeset/better-steaks-dress.md b/.changeset/better-steaks-dress.md new file mode 100644 index 00000000000..6179fc261ac --- /dev/null +++ b/.changeset/better-steaks-dress.md @@ -0,0 +1,5 @@ +--- +'@primer/react': major +--- + +Removes `sx` prop from internal helper components which results in `sx` no longer being available on the TextInput.Label component From 64ad2c63e391d169af78d8f10a6571edaef2713b Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Tue, 30 Sep 2025 17:41:36 -0400 Subject: [PATCH 03/17] fixes FormControlLabel types to adapt to InputLabel changes --- .../src/FormControl/FormControlLabel.tsx | 72 ++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/packages/react/src/FormControl/FormControlLabel.tsx b/packages/react/src/FormControl/FormControlLabel.tsx index 59b6f4a5fcd..d1b0bf6a6c6 100644 --- a/packages/react/src/FormControl/FormControlLabel.tsx +++ b/packages/react/src/FormControl/FormControlLabel.tsx @@ -11,43 +11,51 @@ export type Props = { requiredIndicator?: boolean id?: string className?: string + as?: 'label' | 'legend' | 'span' } -const FormControlLabel: React.FC< - React.PropsWithChildren<{htmlFor?: string} & React.ComponentProps & Props> -> = ({as, children, htmlFor, id, visuallyHidden, requiredIndicator = true, requiredText, className, ...props}) => { +type FormControlLabelProps = React.PropsWithChildren<{htmlFor?: string} & Props> + +const FormControlLabel: React.FC = ({ + as, + children, + htmlFor, + id, + visuallyHidden, + requiredIndicator = true, + requiredText, + className, + ...props +}) => { const {disabled, id: formControlId, required} = useFormControlContext() - /** - * Ensure we can pass through props correctly, since legend/span accept no defined 'htmlFor' - */ - const labelProps: React.ComponentProps = - as === 'legend' || as === 'span' - ? { - as, - id, - className, - visuallyHidden, - required, - requiredText, - requiredIndicator, - disabled, - ...props, - } - : { - as, - id, - className, - visuallyHidden, - htmlFor: htmlFor || formControlId, - required, - requiredText, - requiredIndicator, - disabled, - ...props, - } + // Base props that are common to all element types + const baseProps = { + id, + className, + visuallyHidden, + required, + requiredText, + requiredIndicator, + disabled, + ...props, + } + + // For legend and span elements, don't pass htmlFor + if (as === 'legend' || as === 'span') { + return ( + + {children} + + ) + } - return {children} + // For label elements (default), include htmlFor + return ( + + {children} + + ) } export default FormControlLabel From d24e12a89e9b8dee1649faa0f18bac776a8d2d89 Mon Sep 17 00:00:00 2001 From: Marie Lucca <40550942+francinelucca@users.noreply.github.com> Date: Wed, 1 Oct 2025 08:58:52 -0400 Subject: [PATCH 04/17] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/react/src/internal/components/InputLabel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/internal/components/InputLabel.tsx b/packages/react/src/internal/components/InputLabel.tsx index b1314bfcfb8..47e2ace85e2 100644 --- a/packages/react/src/internal/components/InputLabel.tsx +++ b/packages/react/src/internal/components/InputLabel.tsx @@ -33,7 +33,7 @@ function InputLabel({ className, ...props }: InputLabelProps) { - const Component = as || 'label' + const Component = (as ?? 'label') as ElementType return ( Date: Wed, 1 Oct 2025 18:08:48 -0400 Subject: [PATCH 05/17] reverts type changes to InputLabel --- .../src/internal/components/InputLabel.tsx | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/react/src/internal/components/InputLabel.tsx b/packages/react/src/internal/components/InputLabel.tsx index 47e2ace85e2..2eca1beda87 100644 --- a/packages/react/src/internal/components/InputLabel.tsx +++ b/packages/react/src/internal/components/InputLabel.tsx @@ -1,26 +1,30 @@ import {clsx} from 'clsx' import type React from 'react' -import type {ElementType} from 'react' import classes from './InputLabel.module.css' -import type {PolymorphicProps} from '../../utils/modern-polymorphic' -type InputLabelProps = PolymorphicProps< - As, - 'label', - { - disabled?: boolean - required?: boolean - requiredText?: string - requiredIndicator?: boolean - visuallyHidden?: boolean - } -> & - React.PropsWithChildren +type BaseProps = { + disabled?: boolean + required?: boolean + requiredText?: string + requiredIndicator?: boolean + visuallyHidden?: boolean + id?: string + className?: string +} + +export type LabelProps = BaseProps & { + htmlFor?: string + as?: 'label' +} -export type LabelProps = InputLabelProps<'label'> -export type LegendOrSpanProps = InputLabelProps<'legend' | 'span'> +export type LegendOrSpanProps = BaseProps & { + as: 'legend' | 'span' + htmlFor?: undefined +} + +type Props = React.PropsWithChildren -function InputLabel({ +function InputLabel({ children, disabled, htmlFor, @@ -29,12 +33,14 @@ function InputLabel({ requiredText, requiredIndicator, visuallyHidden, - as, + as = 'label', className, ...props -}: InputLabelProps) { - const Component = (as ?? 'label') as ElementType +}: Props) { + const Component = as + return ( + // @ts-ignore weird typing issue with union for `as` prop Date: Wed, 1 Oct 2025 20:28:21 -0400 Subject: [PATCH 06/17] bring back InputLabel props to FormControlLabel --- packages/react/src/FormControl/FormControlLabel.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react/src/FormControl/FormControlLabel.tsx b/packages/react/src/FormControl/FormControlLabel.tsx index d1b0bf6a6c6..890418ede04 100644 --- a/packages/react/src/FormControl/FormControlLabel.tsx +++ b/packages/react/src/FormControl/FormControlLabel.tsx @@ -14,7 +14,9 @@ export type Props = { as?: 'label' | 'legend' | 'span' } -type FormControlLabelProps = React.PropsWithChildren<{htmlFor?: string} & Props> +type FormControlLabelProps = React.PropsWithChildren< + {htmlFor?: string} & React.ComponentProps & Props +> const FormControlLabel: React.FC = ({ as, From d4dd920f86f7b695793888a06e19ac8019bb3680 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 1 Oct 2025 21:48:18 -0400 Subject: [PATCH 07/17] exports FormControl.Label from styled-react --- packages/styled-react/src/components/FormControl.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/styled-react/src/components/FormControl.tsx b/packages/styled-react/src/components/FormControl.tsx index b4affd914be..66bbaf1a33a 100644 --- a/packages/styled-react/src/components/FormControl.tsx +++ b/packages/styled-react/src/components/FormControl.tsx @@ -4,6 +4,7 @@ import { type FormControlProps as PrimerFormControlProps, type FormControlCaptionProps as PrimerFormControlCaptionProps, type FormControlValidationProps as PrimerFormControlValidationProps, + type FormControlLabelProps as PrimerFormControlLabelProps, type SxProp, } from '@primer/react' import {forwardRef, type PropsWithChildren} from 'react' @@ -29,16 +30,22 @@ const FormControlLeadingVisual = (props: PropsWithChildren) => { return } +type FormControlLabelProps = PropsWithChildren & SxProp + +const FormControlLabel = (props: FormControlLabelProps) => { + return +} + const FormControl = Object.assign(FormControlImpl, { Caption: FormControlCaption, LeadingVisual: FormControlLeadingVisual, Validation: FormControlValidation, - Label: PrimerFormControl.Label, + Label: FormControlLabel, }) as typeof FormControlImpl & { Caption: typeof FormControlCaption LeadingVisual: typeof FormControlLeadingVisual Validation: typeof FormControlValidation - Label: typeof PrimerFormControl.Label + Label: typeof FormControlLabel } export {FormControl, type FormControlProps} From 3328862319ba7b747ea2bd5b5d6581c74342435b Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 1 Oct 2025 22:29:15 -0400 Subject: [PATCH 08/17] fixes typo --- packages/react/src/FormControl/FormControlLabel.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react/src/FormControl/FormControlLabel.tsx b/packages/react/src/FormControl/FormControlLabel.tsx index 890418ede04..ac8a7befbf8 100644 --- a/packages/react/src/FormControl/FormControlLabel.tsx +++ b/packages/react/src/FormControl/FormControlLabel.tsx @@ -14,9 +14,7 @@ export type Props = { as?: 'label' | 'legend' | 'span' } -type FormControlLabelProps = React.PropsWithChildren< - {htmlFor?: string} & React.ComponentProps & Props -> +type FormControlLabelProps = React.PropsWithChildren & Props> const FormControlLabel: React.FC = ({ as, From 90a094684fdac3316b67bc4c0c16e473935e062b Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 2 Oct 2025 23:28:29 -0400 Subject: [PATCH 09/17] revert styled FormControl changes --- packages/styled-react/src/components/FormControl.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/styled-react/src/components/FormControl.tsx b/packages/styled-react/src/components/FormControl.tsx index 66bbaf1a33a..0d620f1e7cf 100644 --- a/packages/styled-react/src/components/FormControl.tsx +++ b/packages/styled-react/src/components/FormControl.tsx @@ -30,22 +30,16 @@ const FormControlLeadingVisual = (props: PropsWithChildren) => { return } -type FormControlLabelProps = PropsWithChildren & SxProp - -const FormControlLabel = (props: FormControlLabelProps) => { - return -} - const FormControl = Object.assign(FormControlImpl, { Caption: FormControlCaption, LeadingVisual: FormControlLeadingVisual, Validation: FormControlValidation, - Label: FormControlLabel, + Label: PrimerFormControl.Label, }) as typeof FormControlImpl & { Caption: typeof FormControlCaption LeadingVisual: typeof FormControlLeadingVisual Validation: typeof FormControlValidation - Label: typeof FormControlLabel + Label: typeof PrimerFormControl.Label } export {FormControl, type FormControlProps} From 36b4999e4d430892f850a90e6272e75eafe17977 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 2 Oct 2025 23:28:51 -0400 Subject: [PATCH 10/17] remove unused import --- packages/styled-react/src/components/FormControl.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/styled-react/src/components/FormControl.tsx b/packages/styled-react/src/components/FormControl.tsx index 0d620f1e7cf..b4affd914be 100644 --- a/packages/styled-react/src/components/FormControl.tsx +++ b/packages/styled-react/src/components/FormControl.tsx @@ -4,7 +4,6 @@ import { type FormControlProps as PrimerFormControlProps, type FormControlCaptionProps as PrimerFormControlCaptionProps, type FormControlValidationProps as PrimerFormControlValidationProps, - type FormControlLabelProps as PrimerFormControlLabelProps, type SxProp, } from '@primer/react' import {forwardRef, type PropsWithChildren} from 'react' From 323618516464e050c9899468a6f3d9a72b343ddd Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 08:30:01 -0400 Subject: [PATCH 11/17] remaining sx removals --- packages/react/src/AvatarStack/AvatarStack.tsx | 6 ++---- .../CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx | 10 +++------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/react/src/AvatarStack/AvatarStack.tsx b/packages/react/src/AvatarStack/AvatarStack.tsx index 6ad04ffb750..9661161a24c 100644 --- a/packages/react/src/AvatarStack/AvatarStack.tsx +++ b/packages/react/src/AvatarStack/AvatarStack.tsx @@ -7,7 +7,6 @@ import {isResponsiveValue} from '../hooks/useResponsiveValue' import type {WidthOnlyViewportRangeKeys} from '../utils/types/ViewportRangeKeys' import classes from './AvatarStack.module.css' import {hasInteractiveNodes} from '../internal/utils/hasInteractiveNodes' -import {BoxWithFallback} from '../internal/components/BoxWithFallback' const transformChildren = (children: React.ReactNode, shape: AvatarStackProps['shape']) => { return React.Children.map(children, child => { @@ -158,8 +157,7 @@ const AvatarStack = ({ } return ( - 3 ? '3+' : count} @@ -187,7 +185,7 @@ const AvatarStack = ({ {' '} {transformChildren(children, shape)} - + ) } diff --git a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx index e69139bb51d..03d9aaa75e9 100644 --- a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx +++ b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx @@ -7,10 +7,8 @@ import CheckboxOrRadioGroupValidation from './CheckboxOrRadioGroupValidation' import CheckboxOrRadioGroupContext from './CheckboxOrRadioGroupContext' import VisuallyHidden from '../../../_VisuallyHidden' import {useSlots} from '../../../hooks/useSlots' -import type {SxProp} from '../../../sx' import classes from './CheckboxOrRadioGroup.module.css' import {clsx} from 'clsx' -import {BoxWithFallback} from '../BoxWithFallback' export type CheckboxOrRadioGroupProps = { /** Class name for custom styling */ @@ -32,7 +30,7 @@ export type CheckboxOrRadioGroupProps = { * If true, the user must make a selection before the owning form can be submitted */ required?: boolean -} & SxProp +} const CheckboxOrRadioGroup: React.FC> = ({ 'aria-labelledby': ariaLabelledby, @@ -41,7 +39,6 @@ const CheckboxOrRadioGroup: React.FC { const [slots, rest] = useSlots(children, { caption: CheckboxOrRadioGroupCaption, @@ -80,7 +77,7 @@ const CheckboxOrRadioGroup: React.FC
- {labelChild ? ( /* @@ -126,7 +122,7 @@ const CheckboxOrRadioGroup: React.FC {React.Children.toArray(rest).filter(child => React.isValidElement(child))}
-
+ {validationChild && ( From 48d4b1f325dcdf2909312a311178a6d5ea776cc0 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 08:49:08 -0400 Subject: [PATCH 12/17] chore: remove remaining sx usage --- packages/react/src/Button/LinkButton.tsx | 2 +- packages/react/src/CheckboxGroup/CheckboxGroup.stories.tsx | 2 +- packages/react/src/Radio/Radio.stories.tsx | 2 +- packages/react/src/RadioGroup/RadioGroup.stories.tsx | 2 +- packages/react/src/UnderlineNav/UnderlineNav.stories.tsx | 2 +- packages/react/src/utils/form-story-helpers.tsx | 2 +- packages/react/src/utils/story-helpers.tsx | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react/src/Button/LinkButton.tsx b/packages/react/src/Button/LinkButton.tsx index 73cc704ffc1..bac52d497b3 100644 --- a/packages/react/src/Button/LinkButton.tsx +++ b/packages/react/src/Button/LinkButton.tsx @@ -3,7 +3,7 @@ import type {LinkButtonProps as BaseLinkButtonProps, ButtonProps} from './types' import {ButtonBase} from './ButtonBase' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' -export type LinkButtonProps = Omit +export type LinkButtonProps = BaseLinkButtonProps & ButtonProps const LinkButton = forwardRef(({children, as: Component = 'a', ...props}, forwardedRef): JSX.Element => { return ( diff --git a/packages/react/src/CheckboxGroup/CheckboxGroup.stories.tsx b/packages/react/src/CheckboxGroup/CheckboxGroup.stories.tsx index ea7800d72c7..7c224f5cb31 100644 --- a/packages/react/src/CheckboxGroup/CheckboxGroup.stories.tsx +++ b/packages/react/src/CheckboxGroup/CheckboxGroup.stories.tsx @@ -5,7 +5,7 @@ import type {CheckboxOrRadioGroupArgs} from '../utils/form-story-helpers' export default { title: 'Components/CheckboxGroup', component: CheckboxGroup, - parameters: {controls: {exclude: ['aria-labelledby', 'id', 'onChange', 'sx']}}, + parameters: {controls: {exclude: ['aria-labelledby', 'id', 'onChange']}}, } as Meta export const Playground = ({ diff --git a/packages/react/src/Radio/Radio.stories.tsx b/packages/react/src/Radio/Radio.stories.tsx index b6e38f765e9..c7be73a83f4 100644 --- a/packages/react/src/Radio/Radio.stories.tsx +++ b/packages/react/src/Radio/Radio.stories.tsx @@ -8,7 +8,7 @@ import { getFormControlArgsByChildComponent, } from '../utils/form-story-helpers' -const excludedControlKeys = ['required', 'value', 'name', 'validationStatus', 'sx'] +const excludedControlKeys = ['required', 'value', 'name', 'validationStatus'] export default { title: 'Components/Radio', diff --git a/packages/react/src/RadioGroup/RadioGroup.stories.tsx b/packages/react/src/RadioGroup/RadioGroup.stories.tsx index bb8d9d5f666..7da9daeea13 100644 --- a/packages/react/src/RadioGroup/RadioGroup.stories.tsx +++ b/packages/react/src/RadioGroup/RadioGroup.stories.tsx @@ -5,7 +5,7 @@ import type {CheckboxOrRadioGroupArgs} from '../utils/form-story-helpers' export default { title: 'Components/RadioGroup', component: RadioGroup, - parameters: {controls: {exclude: ['aria-labelledby', 'id', 'onChange', 'sx']}}, + parameters: {controls: {exclude: ['aria-labelledby', 'id', 'onChange']}}, } as Meta export const Playground = ({ diff --git a/packages/react/src/UnderlineNav/UnderlineNav.stories.tsx b/packages/react/src/UnderlineNav/UnderlineNav.stories.tsx index 05a5d0d60cc..de81d856e38 100644 --- a/packages/react/src/UnderlineNav/UnderlineNav.stories.tsx +++ b/packages/react/src/UnderlineNav/UnderlineNav.stories.tsx @@ -2,7 +2,7 @@ import type {Meta, StoryFn} from '@storybook/react-vite' import {UnderlineNav} from './index' import {UnderlineNavItem} from './UnderlineNavItem' -const excludedControlKeys = ['sx', 'as', 'align', 'afterSelect'] +const excludedControlKeys = ['as', 'align', 'afterSelect'] const meta: Meta = { title: 'Components/UnderlineNav', diff --git a/packages/react/src/utils/form-story-helpers.tsx b/packages/react/src/utils/form-story-helpers.tsx index f2a125c0553..899cbfe1015 100644 --- a/packages/react/src/utils/form-story-helpers.tsx +++ b/packages/react/src/utils/form-story-helpers.tsx @@ -109,7 +109,7 @@ export const getTextInputArgTypes = (category?: string) => return obj }, {}) -export const textInputExcludedControlKeys = ['as', 'icon', 'leadingVisual', 'sx', 'trailingVisual', 'trailingAction'] +export const textInputExcludedControlKeys = ['as', 'icon', 'leadingVisual', 'trailingVisual', 'trailingAction'] export const textInputWithTokensArgTypes: ArgTypes = { hideTokenRemoveButtons: { diff --git a/packages/react/src/utils/story-helpers.tsx b/packages/react/src/utils/story-helpers.tsx index b95d429733a..5c33c478289 100644 --- a/packages/react/src/utils/story-helpers.tsx +++ b/packages/react/src/utils/story-helpers.tsx @@ -110,7 +110,7 @@ export const getTextInputArgTypes = (category?: string) => return obj }, {}) -export const textInputExcludedControlKeys = ['as', 'icon', 'leadingVisual', 'sx', 'trailingVisual', 'trailingAction'] +export const textInputExcludedControlKeys = ['as', 'icon', 'leadingVisual', 'trailingVisual', 'trailingAction'] export const textInputWithTokensArgTypes: ArgTypes = { hideTokenRemoveButtons: { From 155488be7776b8e032b86c51b5423dc15e378157 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 09:35:15 -0400 Subject: [PATCH 13/17] remove remaining sx --- packages/react/src/FormControl/_FormControlValidation.tsx | 5 +---- .../CheckboxOrRadioGroup/CheckboxOrRadioGroupValidation.tsx | 6 ++---- packages/react/src/internal/components/InputValidation.tsx | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/react/src/FormControl/_FormControlValidation.tsx b/packages/react/src/FormControl/_FormControlValidation.tsx index 6678eaf8153..0c58021a400 100644 --- a/packages/react/src/FormControl/_FormControlValidation.tsx +++ b/packages/react/src/FormControl/_FormControlValidation.tsx @@ -1,6 +1,5 @@ import type React from 'react' import InputValidation from '../internal/components/InputValidation' -import type {SxProp} from '../sx' import type {FormValidationStatus} from '../utils/types/FormValidationStatus' import {useFormControlContext} from './_FormControlContext' @@ -9,13 +8,12 @@ export type FormControlValidationProps = { id?: string className?: string style?: React.CSSProperties -} & SxProp +} const FormControlValidation: React.FC> = ({ children, className, variant, - sx, id, style, }) => { @@ -25,7 +23,6 @@ const FormControlValidation: React.FC {children} diff --git a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupValidation.tsx b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupValidation.tsx index 34cc2c084cd..c42928622be 100644 --- a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupValidation.tsx +++ b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupValidation.tsx @@ -1,22 +1,20 @@ import React from 'react' import InputValidation from '../InputValidation' -import type {SxProp} from '../../../sx' import type {FormValidationStatus} from '../../../utils/types/FormValidationStatus' import CheckboxOrRadioGroupContext from './CheckboxOrRadioGroupContext' export type CheckboxOrRadioGroupValidationProps = { /** Changes the visual style to match the validation status */ variant: FormValidationStatus -} & SxProp +} const CheckboxOrRadioGroupValidation: React.FC> = ({ children, variant, - sx, }) => { const {validationMessageId = ''} = React.useContext(CheckboxOrRadioGroupContext) return ( - + {children} ) diff --git a/packages/react/src/internal/components/InputValidation.tsx b/packages/react/src/internal/components/InputValidation.tsx index 22809a452fa..e013cab6948 100644 --- a/packages/react/src/internal/components/InputValidation.tsx +++ b/packages/react/src/internal/components/InputValidation.tsx @@ -2,7 +2,6 @@ import type {IconProps} from '@primer/octicons-react' import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react' import type React from 'react' import Text from '../../Text' -import type {SxProp} from '../../sx' import type {FormValidationStatus} from '../../utils/types/FormValidationStatus' import classes from './InputValidation.module.css' import {clsx} from 'clsx' @@ -12,7 +11,7 @@ type Props = { id: string validationStatus?: FormValidationStatus style?: React.CSSProperties -} & SxProp +} const validationIconMap: Record< NonNullable, From 514a572b9e9875522ad251c6928868e4f1d547d1 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 09:36:17 -0400 Subject: [PATCH 14/17] remove remaining sx --- .../CheckboxOrRadioGroup/CheckboxOrRadioGroupCaption.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupCaption.tsx b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupCaption.tsx index 1aa1bcd45b3..7b89c12fc0a 100644 --- a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupCaption.tsx +++ b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroupCaption.tsx @@ -1,11 +1,10 @@ import React from 'react' import Text from '../../../Text' -import type {SxProp} from '../../../sx' import CheckboxOrRadioGroupContext from './CheckboxOrRadioGroupContext' import classes from './CheckboxOrRadioGroup.module.css' import {clsx} from 'clsx' -type CheckboxOrRadioGroupCaptionProps = React.PropsWithChildren & {className?: string} +type CheckboxOrRadioGroupCaptionProps = React.PropsWithChildren<{className?: string}> const CheckboxOrRadioGroupCaption: React.FC = ({className, children}) => { const {captionId} = React.useContext(CheckboxOrRadioGroupContext) From b0ac7d8ec4edf103e97738c45b7f791999fc5550 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 15:27:50 -0400 Subject: [PATCH 15/17] refactor FormControlLabel --- .../src/FormControl/FormControlLabel.tsx | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/packages/react/src/FormControl/FormControlLabel.tsx b/packages/react/src/FormControl/FormControlLabel.tsx index f3c39e76ea4..b9e14cbc23e 100644 --- a/packages/react/src/FormControl/FormControlLabel.tsx +++ b/packages/react/src/FormControl/FormControlLabel.tsx @@ -12,51 +12,43 @@ export type Props = { id?: string className?: string style?: React.CSSProperties - as?: 'label' | 'legend' | 'span' } -type FormControlLabelProps = React.PropsWithChildren & Props> - -const FormControlLabel: React.FC = ({ - as, - children, - htmlFor, - id, - visuallyHidden, - requiredIndicator = true, - requiredText, - className, - ...props -}) => { +const FormControlLabel: React.FC< + React.PropsWithChildren<{htmlFor?: string} & React.ComponentProps & Props> +> = ({as, children, htmlFor, id, visuallyHidden, requiredIndicator = true, requiredText, className, ...props}) => { const {disabled, id: formControlId, required} = useFormControlContext() - // Base props that are common to all element types - const baseProps = { - id, - className, - visuallyHidden, - required, - requiredText, - requiredIndicator, - disabled, - ...props, - } - - // For legend and span elements, don't pass htmlFor - if (as === 'legend' || as === 'span') { - return ( - - {children} - - ) - } + /** + * Ensure we can pass through props correctly, since legend/span accept no defined 'htmlFor' + */ + const labelProps: React.ComponentProps = + as === 'legend' || as === 'span' + ? { + as, + id, + className, + visuallyHidden, + required, + requiredText, + requiredIndicator, + disabled, + ...props, + } + : { + as, + id, + className, + visuallyHidden, + htmlFor: htmlFor || formControlId, + required, + requiredText, + requiredIndicator, + disabled, + ...props, + } - // For label elements (default), include htmlFor - return ( - - {children} - - ) + return {children} } export default FormControlLabel From 17c99efde4819fd85e2fd757921feddd1cc397b2 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 16:17:00 -0400 Subject: [PATCH 16/17] component wrapper fix --- .../CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx index 03d9aaa75e9..c2611b6f29a 100644 --- a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx +++ b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx @@ -9,6 +9,7 @@ import VisuallyHidden from '../../../_VisuallyHidden' import {useSlots} from '../../../hooks/useSlots' import classes from './CheckboxOrRadioGroup.module.css' import {clsx} from 'clsx' +import {BoxWithFallback} from '../BoxWithFallback' export type CheckboxOrRadioGroupProps = { /** Class name for custom styling */ @@ -67,6 +68,8 @@ const CheckboxOrRadioGroup: React.FC
-
{React.Children.toArray(rest).filter(child => React.isValidElement(child))}
-
+ {validationChild && ( From 25143fed1a35650fedde576fefbd5a94e4afddb0 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Mon, 6 Oct 2025 16:22:43 -0400 Subject: [PATCH 17/17] lint --- .../components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx index c2611b6f29a..a53899e3eb0 100644 --- a/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx +++ b/packages/react/src/internal/components/CheckboxOrRadioGroup/CheckboxOrRadioGroup.tsx @@ -9,7 +9,6 @@ import VisuallyHidden from '../../../_VisuallyHidden' import {useSlots} from '../../../hooks/useSlots' import classes from './CheckboxOrRadioGroup.module.css' import {clsx} from 'clsx' -import {BoxWithFallback} from '../BoxWithFallback' export type CheckboxOrRadioGroupProps = { /** Class name for custom styling */