Skip to content
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/grumpy-lobsters-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': major
---

Update FormControl component to no longer support sx
27 changes: 1 addition & 26 deletions packages/react/src/FormControl/FormControl.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@
"description": "Class name(s) for custom styling.",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject",
"deprecated": true
},
{
"name": "ref",
"type": "React.RefObject<HTMLDivElement>"
Expand Down Expand Up @@ -152,11 +147,6 @@
"type": "string",
"description": "Class name(s) for custom styling.",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject",
"deprecated": true
}
]
},
Expand All @@ -174,11 +164,6 @@
"type": "React.ReactNode",
"defaultValue": "",
"description": "The content (usually just text) that is rendered to give contextual info about the field"
},
{
"name": "sx",
"type": "SystemStyleObject",
"deprecated": true
}
]
},
Expand All @@ -203,11 +188,6 @@
"type": "string",
"description": "May be used to override the ID assigned by FormControl's React Context",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject",
"deprecated": true
}
]
},
Expand All @@ -219,13 +199,8 @@
"type": "React.ReactNode",
"defaultValue": "",
"description": "The visual to render before the choice input's label"
},
{
"name": "sx",
"type": "SystemStyleObject",
"deprecated": true
}
]
}
]
}
}
16 changes: 6 additions & 10 deletions packages/react/src/FormControl/FormControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Textarea from '../Textarea'
import {CheckboxOrRadioGroupContext} from '../internal/components/CheckboxOrRadioGroup'
import ValidationAnimationContainer from '../internal/components/ValidationAnimationContainer'
import {useSlots} from '../hooks/useSlots'
import type {SxProp} from '../sx'
import {useId} from '../hooks/useId'
import {FormControlCaption} from './FormControlCaption'
import FormControlLabel from './FormControlLabel'
Expand All @@ -20,7 +19,6 @@ import FormControlValidation from './_FormControlValidation'
import {FormControlContextProvider} from './_FormControlContext'
import {warning} from '../utils/warning'
import classes from './FormControl.module.css'
import {BoxWithFallback} from '../internal/components/BoxWithFallback'
import {isSlot} from '../utils/is-slot'

export type FormControlProps = {
Expand All @@ -44,10 +42,10 @@ export type FormControlProps = {
layout?: 'horizontal' | 'vertical'
className?: string
style?: React.CSSProperties
} & SxProp
}

const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
({children, disabled: disabledProp, layout = 'vertical', id: idProp, required, sx, className, style}, ref) => {
({children, disabled: disabledProp, layout = 'vertical', id: idProp, required, className, style}, ref) => {
const [slots, childrenWithoutSlots] = useSlots(children, {
caption: FormControlCaption,
label: FormControlLabel,
Expand Down Expand Up @@ -179,20 +177,18 @@ const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
}}
>
{isChoiceInput || layout === 'horizontal' ? (
<BoxWithFallback
<div
ref={ref}
data-has-leading-visual={slots.leadingVisual ? '' : undefined}
sx={sx}
className={clsx(className, classes.ControlHorizontalLayout)}
style={style}
>
{InputChildren}
</BoxWithFallback>
</div>
) : (
<BoxWithFallback
<div
ref={ref}
data-has-label={!isLabelHidden ? '' : undefined}
sx={sx}
className={clsx(className, classes.ControlVerticalLayout)}
style={style}
>
Expand Down Expand Up @@ -222,7 +218,7 @@ const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
<ValidationAnimationContainer show>{slots.validation}</ValidationAnimationContainer>
) : null}
{slots.caption}
</BoxWithFallback>
</div>
)}
</FormControlContextProvider>
)
Expand Down
22 changes: 8 additions & 14 deletions packages/react/src/FormControl/FormControlCaption.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
import {clsx} from 'clsx'
import type React from 'react'
import Text from '../Text'
import type {SxProp} from '../sx'
import classes from './FormControlCaption.module.css'
import {useFormControlContext} from './_FormControlContext'
import {BoxWithFallback} from '../internal/components/BoxWithFallback'

type FormControlCaptionProps = React.PropsWithChildren<
{
id?: string
className?: string
style?: React.CSSProperties
} & SxProp
>
export type FormControlCaptionProps = React.PropsWithChildren<{
id?: string
className?: string
style?: React.CSSProperties
}>

function FormControlCaption({id, children, sx, className, style}: FormControlCaptionProps) {
function FormControlCaption({id, children, className, style}: FormControlCaptionProps) {
const {captionId, disabled} = useFormControlContext()

return (
<BoxWithFallback
as={Text}
<Text
id={id ?? captionId}
className={clsx(className, classes.Caption)}
data-control-disabled={disabled ? '' : undefined}
sx={sx}
style={style}
>
{children}
</BoxWithFallback>
</Text>
)
}

Expand Down
7 changes: 2 additions & 5 deletions packages/react/src/FormControl/FormControlLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type React from 'react'
import type {SxProp} from '../sx'
import {useFormControlContext} from './_FormControlContext'
import {InputLabel} from '../internal/components/InputLabel'
import type {FCWithSlotMarker} from '../utils/types'
Expand All @@ -14,11 +13,11 @@ export type Props = {
id?: string
className?: string
style?: React.CSSProperties
} & SxProp
}

const FormControlLabel: FCWithSlotMarker<
React.PropsWithChildren<{htmlFor?: string} & React.ComponentProps<typeof InputLabel> & Props>
> = ({as, children, htmlFor, id, visuallyHidden, requiredIndicator = true, requiredText, sx, className, ...props}) => {
> = ({as, children, htmlFor, id, visuallyHidden, requiredIndicator = true, requiredText, className, ...props}) => {
const {disabled, id: formControlId, required} = useFormControlContext()

/**
Expand All @@ -35,7 +34,6 @@ const FormControlLabel: FCWithSlotMarker<
requiredText,
requiredIndicator,
disabled,
sx,
...props,
}
: {
Expand All @@ -48,7 +46,6 @@ const FormControlLabel: FCWithSlotMarker<
requiredText,
requiredIndicator,
disabled,
sx,
...props,
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.LeadingVisual {
--leadingVisual-size: 16px;

color: var(--fgColor-default);
display: flex;
align-items: center;

&:where([data-control-disabled]) {
color: var(--control-fgColor-disabled);
}

& > * {
min-width: var(--leadingVisual-size);
min-height: var(--leadingVisual-size);
fill: currentColor;
}

&:where([data-has-caption]) {
--leadingVisual-size: 24px;
}
}
38 changes: 5 additions & 33 deletions packages/react/src/FormControl/FormControlLeadingVisual.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,25 @@
import type React from 'react'
import type {SxProp} from '../sx'
import {useFormControlContext} from './_FormControlContext'
import styled from 'styled-components'
import sx from '../sx'
import classes from './FormControlLeadingVisual.module.css'
import type {FCWithSlotMarker} from '../utils/types'

const FormControlLeadingVisual: FCWithSlotMarker<React.PropsWithChildren<SxProp & {style?: React.CSSProperties}>> = ({
const FormControlLeadingVisual: FCWithSlotMarker<React.PropsWithChildren<{style?: React.CSSProperties}>> = ({
children,
sx,
style,
}) => {
const {disabled, captionId} = useFormControlContext()
return (
<StyledLeadingVisual
<div
className={classes.LeadingVisual}
data-control-disabled={disabled ? '' : undefined}
style={style}
data-has-caption={captionId ? '' : undefined}
sx={sx}
>
{children}
</StyledLeadingVisual>
</div>
)
}

const StyledLeadingVisual = styled.div`
--leadingVisual-size: var(--text-title-size-small);

color: var(--fgColor-default);

display: flex;
align-items: center; /* Vertical alignment */

&:where([data-control-disabled]) {
color: var(--control-fgColor-disabled);
}

& > * {
min-width: var(--leadingVisual-size);
min-height: var(--leadingVisual-size);
fill: currentColor;
}

&:where([data-has-caption]) {
--leadingVisual-size: var(--base-size-24);
}

${sx}
`

FormControlLeadingVisual.__SLOT__ = Symbol('FormControl.LeadingVisual')

export default FormControlLeadingVisual
5 changes: 1 addition & 4 deletions packages/react/src/FormControl/_FormControlValidation.tsx
Original file line number Diff line number Diff line change
@@ -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'
import type {FCWithSlotMarker} from '../utils/types'
Expand All @@ -10,13 +9,12 @@ export type FormControlValidationProps = {
id?: string
className?: string
style?: React.CSSProperties
} & SxProp
}

const FormControlValidation: FCWithSlotMarker<React.PropsWithChildren<FormControlValidationProps>> = ({
children,
className,
variant,
sx,
id,
style,
}) => {
Expand All @@ -26,7 +24,6 @@ const FormControlValidation: FCWithSlotMarker<React.PropsWithChildren<FormContro
className={className}
validationStatus={variant}
id={id || validationMessageId || ''}
sx={sx}
style={style}
>
{children}
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/FormControl/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export {useFormControlForwardedProps} from './_FormControlContext'
export {default} from './FormControl'
export type {FormControlProps} from './FormControl'
export type {FormControlCaptionProps} from './FormControlCaption'
export type {Props as FormControlLabelProps} from './FormControlLabel'
export type {FormControlValidationProps} from './_FormControlValidation'
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ exports[`@primer/react > should not update exports without a semver change 1`] =
"type FocusTrapHookSettings",
"type FocusZoneHookSettings",
"FormControl",
"type FormControlCaptionProps",
"type FormControlLabelProps",
"type FormControlProps",
"type FormControlValidationProps",
"Header",
"type HeaderItemProps",
"type HeaderLinkProps",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1078,11 +1078,11 @@ const CreateNewLabelDialog = ({
Note this Dialog is not accessible. Do not copy this.
</Flash>
<form onSubmit={onSubmit}>
<FormControl sx={{marginBottom: 2}}>
<FormControl className={classes.FormControl}>
<FormControl.Label>Name</FormControl.Label>
<TextInput name="name" block defaultValue={initialValue} autoFocus />
</FormControl>
<FormControl sx={{marginBottom: 2}}>
<FormControl className={classes.FormControl}>
<FormControl.Label>Color</FormControl.Label>
<TextInput name="color" block defaultValue="fae17d" leadingVisual="#" />
</FormControl>
Expand Down
6 changes: 6 additions & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ export {ConfirmationDialog} from './ConfirmationDialog/ConfirmationDialog'
export {default as Flash} from './Flash'
export type {FlashProps} from './Flash'
export {default as FormControl} from './FormControl'
export type {
FormControlProps,
FormControlCaptionProps,
FormControlLabelProps,
FormControlValidationProps,
} from './FormControl'
export {useFormControlForwardedProps} from './FormControl'
export {default as Header} from './Header'
export type {HeaderProps, HeaderItemProps, HeaderLinkProps} from './Header'
Expand Down
Loading
Loading