feat: Support help text in Checkbox, Radio, and Switch#9877
feat: Support help text in Checkbox, Radio, and Switch#9877snowystinger merged 13 commits intomainfrom
Conversation
|
Build successful! 🎉 |
|
Build successful! 🎉 |
|
Build successful! 🎉 |
| ref: RefCallback<any> | ||
| } | ||
|
|
||
| export function useSlotId2(initialState: boolean | (() => boolean) = true): SlotAria { |
|
Build successful! 🎉 |
|
Build successful! 🎉 |
| size: { | ||
| size: { |
There was a problem hiding this comment.
lol this made me do a double take
| const radioField = style({ | ||
| display: 'grid', | ||
| gridTemplateColumns: ['max-content', '1fr'], |
There was a problem hiding this comment.
nit: the field and wrapper styling is quite similar across the Checkbox/RadioGroup/Switch, might be worthwhile reusing/extracting the shared styles so we don't have to remember to update across all 3 places if something changes. That being said, colocation is nice
|
|
||
| <ExampleSwitcher> | ||
| ```tsx render docs={vanillaDocs.exports.CheckboxGroup} links={vanillaDocs.links} props={['label', 'description', 'isDisabled']} initialProps={{label: 'Favorite sports'}} type="vanilla" files={["starters/docs/src/CheckboxGroup.tsx", "starters/docs/src/CheckboxGroup.css"]} | ||
| ```tsx render docs={vanillaDocs.exports.CheckboxGroup} links={vanillaDocs.links} props={['label', 'description', 'isDisabled']} initialProps={{label: 'Email Notification Preferences'}} type="vanilla" files={["starters/docs/src/CheckboxGroup.tsx", "starters/docs/src/CheckboxGroup.css"]} |
There was a problem hiding this comment.
I noticed that the description added via the control here doesn't get an id attached to it, do we need to add useSlotId2 somewhere else too (useField)?
There was a problem hiding this comment.
oh boy, that looks pre-existing. I think yes we need to migrate from useSlotId to useSlotId2 everywhere, but that's quite a big task and possibly a breaking change given that it now includes a ref that people will need to merge (or be sure they are using mergeProps everywhere). I felt ok with it here since these are new slots but will need to consider it more carefully for existing places. I think we should handle that separately from this PR.
|
|
||
| export const RadioGroupContext = createContext<ContextValue<RadioGroupProps, HTMLDivElement>>(null); | ||
| export const RadioContext = createContext<ContextValue<Partial<RadioProps>, HTMLLabelElement>>(null); | ||
| export const RadioFieldContext = createContext<ContextValue<Partial<RadioProps>, HTMLDivElement>>(null); |
There was a problem hiding this comment.
should this be RadioFieldProps instead of RadioProps? Noticed something similar in Switch for its FieldContext
|
Build successful! 🎉 |
|
Build successful! 🎉 |
LFDanLu
left a comment
There was a problem hiding this comment.
pushed a small change to make the RAC RadioGroup/Switch examples also grey out the help text when disabled, but otherwise looks good to me
|
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:Switch Switch {
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<SwitchRenderProps>
className?: ClassNameOrFunction<SwitchRenderProps> = 'react-aria-Switch'
defaultSelected?: boolean
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
isReadOnly?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchRenderProps>
slot?: string | null
style?: StyleOrFunction<SwitchRenderProps>
value?: string/react-aria-components:SwitchProps SwitchProps {
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<SwitchRenderProps>
className?: ClassNameOrFunction<SwitchRenderProps> = 'react-aria-Switch'
defaultSelected?: boolean
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
isReadOnly?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchRenderProps>
slot?: string | null
style?: StyleOrFunction<SwitchRenderProps>
value?: string/react-aria-components:CheckboxField+CheckboxField {
+ aria-controls?: string
+ aria-describedby?: string
+ aria-details?: string
+ aria-errormessage?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<CheckboxFieldRenderProps>
+ className?: ClassNameOrFunction<CheckboxFieldRenderProps> = 'react-aria-CheckboxField'
+ defaultSelected?: boolean
+ excludeFromTabOrder?: boolean
+ form?: string
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ isIndeterminate?: boolean
+ isInvalid?: boolean
+ isReadOnly?: boolean
+ isRequired?: boolean
+ isSelected?: boolean
+ name?: string
+ onBlur?: (FocusEvent<Target>) => void
+ onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<CheckboxFieldRenderProps>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
+ value?: string
+}/react-aria-components:CheckboxButton+CheckboxButton {
+ children?: ChildrenOrFunction<CheckboxButtonRenderProps>
+ className?: ClassNameOrFunction<CheckboxButtonRenderProps> = 'react-aria-CheckboxButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<CheckboxButtonRenderProps>
+}/react-aria-components:CheckboxFieldContext+CheckboxFieldContext {
+ UNTYPED
+}/react-aria-components:RadioField+RadioField {
+ aria-describedby?: string
+ aria-details?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<RadioFieldRenderProps>
+ className?: ClassNameOrFunction<RadioFieldRenderProps> = 'react-aria-RadioField'
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ onBlur?: (FocusEvent<Target>) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<RadioFieldRenderProps>
+ value: string
+}/react-aria-components:RadioButton+RadioButton {
+ children?: ChildrenOrFunction<RadioButtonRenderProps>
+ className?: ClassNameOrFunction<RadioButtonRenderProps> = 'react-aria-RadioButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<RadioButtonRenderProps>
+}/react-aria-components:RadioFieldContext+RadioFieldContext {
+ UNTYPED
+}/react-aria-components:SwitchField+SwitchField {
+ aria-controls?: string
+ aria-describedby?: string
+ aria-details?: string
+ aria-errormessage?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<SwitchFieldRenderProps>
+ className?: ClassNameOrFunction<SwitchFieldRenderProps> = 'react-aria-SwitchField'
+ defaultSelected?: boolean
+ excludeFromTabOrder?: boolean
+ form?: string
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ isInvalid?: boolean
+ isReadOnly?: boolean
+ isRequired?: boolean
+ isSelected?: boolean
+ name?: string
+ onBlur?: (FocusEvent<Target>) => void
+ onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<SwitchFieldRenderProps>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
+ value?: string
+}/react-aria-components:SwitchButton+SwitchButton {
+ children?: ChildrenOrFunction<SwitchButtonRenderProps>
+ className?: ClassNameOrFunction<SwitchButtonRenderProps> = 'react-aria-SwitchButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<SwitchButtonRenderProps>
+}/react-aria-components:SwitchFieldContext+SwitchFieldContext {
+ UNTYPED
+}/react-aria-components:CheckboxFieldProps+CheckboxFieldProps {
+ aria-controls?: string
+ aria-describedby?: string
+ aria-details?: string
+ aria-errormessage?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<CheckboxFieldRenderProps>
+ className?: ClassNameOrFunction<CheckboxFieldRenderProps> = 'react-aria-CheckboxField'
+ defaultSelected?: boolean
+ excludeFromTabOrder?: boolean
+ form?: string
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ isIndeterminate?: boolean
+ isInvalid?: boolean
+ isReadOnly?: boolean
+ isRequired?: boolean
+ isSelected?: boolean
+ name?: string
+ onBlur?: (FocusEvent<Target>) => void
+ onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<CheckboxFieldRenderProps>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
+ value?: string
+}/react-aria-components:CheckboxFieldRenderProps+CheckboxFieldRenderProps {
+ isDisabled: boolean
+ isIndeterminate: boolean
+ isInvalid: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+}/react-aria-components:CheckboxButtonProps+CheckboxButtonProps {
+ children?: ChildrenOrFunction<CheckboxButtonRenderProps>
+ className?: ClassNameOrFunction<CheckboxButtonRenderProps> = 'react-aria-CheckboxButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CheckboxButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<CheckboxButtonRenderProps>
+}/react-aria-components:CheckboxButtonRenderProps+CheckboxButtonRenderProps {
+ isDisabled: boolean
+ isFocusVisible: boolean
+ isFocused: boolean
+ isHovered: boolean
+ isIndeterminate: boolean
+ isInvalid: boolean
+ isPressed: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+}/react-aria-components:RadioFieldProps+RadioFieldProps {
+ aria-describedby?: string
+ aria-details?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<RadioFieldRenderProps>
+ className?: ClassNameOrFunction<RadioFieldRenderProps> = 'react-aria-RadioField'
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ onBlur?: (FocusEvent<Target>) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<RadioFieldRenderProps>
+ value: string
+}/react-aria-components:RadioFieldRenderProps+RadioFieldRenderProps {
+ isDisabled: boolean
+ isInvalid: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+}/react-aria-components:RadioButtonProps+RadioButtonProps {
+ children?: ChildrenOrFunction<RadioButtonRenderProps>
+ className?: ClassNameOrFunction<RadioButtonRenderProps> = 'react-aria-RadioButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<RadioButtonRenderProps>
+}/react-aria-components:RadioButtonRenderProps+RadioButtonRenderProps {
+ isDisabled: boolean
+ isFocusVisible: boolean
+ isFocused: boolean
+ isHovered: boolean
+ isInvalid: boolean
+ isPressed: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+}/react-aria-components:SwitchFieldProps+SwitchFieldProps {
+ aria-controls?: string
+ aria-describedby?: string
+ aria-details?: string
+ aria-errormessage?: string
+ aria-label?: string
+ aria-labelledby?: string
+ autoFocus?: boolean
+ children?: ChildrenOrFunction<SwitchFieldRenderProps>
+ className?: ClassNameOrFunction<SwitchFieldRenderProps> = 'react-aria-SwitchField'
+ defaultSelected?: boolean
+ excludeFromTabOrder?: boolean
+ form?: string
+ id?: string
+ inputRef?: RefObject<HTMLInputElement | null>
+ isDisabled?: boolean
+ isInvalid?: boolean
+ isReadOnly?: boolean
+ isRequired?: boolean
+ isSelected?: boolean
+ name?: string
+ onBlur?: (FocusEvent<Target>) => void
+ onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onKeyDown?: (KeyboardEvent) => void
+ onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchFieldRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<SwitchFieldRenderProps>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
+ value?: string
+}/react-aria-components:SwitchFieldRenderProps+SwitchFieldRenderProps {
+ isDisabled: boolean
+ isInvalid: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+ state: ToggleState
+}/react-aria-components:SwitchButtonProps+SwitchButtonProps {
+ children?: ChildrenOrFunction<SwitchButtonRenderProps>
+ className?: ClassNameOrFunction<SwitchButtonRenderProps> = 'react-aria-SwitchButton'
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchButtonRenderProps>
+ slot?: string | null
+ style?: StyleOrFunction<SwitchButtonRenderProps>
+}/react-aria-components:SwitchButtonRenderProps+SwitchButtonRenderProps {
+ isDisabled: boolean
+ isFocusVisible: boolean
+ isFocused: boolean
+ isHovered: boolean
+ isInvalid: boolean
+ isPressed: boolean
+ isReadOnly: boolean
+ isRequired: boolean
+ isSelected: boolean
+ state: ToggleState
+}@react-aria/checkbox/@react-aria/checkbox:CheckboxAria CheckboxAria {
+ descriptionProps: DOMAttributesWithRef<HTMLElement>
+ errorMessageProps: DOMAttributesWithRef<HTMLElement>
inputProps: InputHTMLAttributes<HTMLInputElement>
isDisabled: boolean
isInvalid: boolean
isPressed: boolean
isSelected: boolean
labelProps: LabelHTMLAttributes<HTMLLabelElement>
validationDetails: ValidityState
validationErrors: Array<string>
}@react-aria/radio/@react-aria/radio:RadioAria RadioAria {
+ descriptionProps: DOMAttributesWithRef<HTMLElement>
inputProps: InputHTMLAttributes<HTMLInputElement>
isDisabled: boolean
isPressed: boolean
isSelected: boolean
}@react-aria/switch/@react-aria/switch:SwitchProps SwitchProps {
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
isDisabled?: boolean
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'aria' | 'native' = 'aria'
value?: string
}/@react-aria/switch:AriaSwitchProps AriaSwitchProps {
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
excludeFromTabOrder?: boolean
form?: string
id?: string
isDisabled?: boolean
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'aria' | 'native' = 'aria'
value?: string
}/@react-aria/switch:SwitchAria SwitchAria {
+ descriptionProps: DOMAttributesWithRef<HTMLElement>
+ errorMessageProps: DOMAttributesWithRef<HTMLElement>
inputProps: InputHTMLAttributes<HTMLInputElement>
isDisabled: boolean
+ isInvalid: boolean
isPressed: boolean
isReadOnly: boolean
isSelected: boolean
labelProps: LabelHTMLAttributes<HTMLLabelElement>
+ validationDetails: ValidityState
+ validationErrors: Array<string>
}@react-aria/toggle/@react-aria/toggle:ToggleAria ToggleAria {
+ descriptionProps: DOMAttributesWithRef<HTMLElement>
+ errorMessageProps: DOMAttributesWithRef<HTMLElement>
inputProps: InputHTMLAttributes<HTMLInputElement>
isDisabled: boolean
isInvalid: boolean
isPressed: boolean
isReadOnly: boolean
isSelected: boolean
labelProps: LabelHTMLAttributes<HTMLLabelElement>
+ validationDetails: ValidityState
+ validationErrors: Array<string>
}@react-spectrum/s2/@react-spectrum/s2:Checkbox Checkbox {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-controls?: string
aria-describedby?: string
aria-details?: string
aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
+ description?: ReactNode
+ errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isEmphasized?: boolean
isIndeterminate?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
validate?: (boolean) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: string
}/@react-spectrum/s2:Radio Radio {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
+ description?: ReactNode
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
onBlur?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
slot?: string | null
styles?: StylesProp
value: string
}/@react-spectrum/s2:Switch Switch {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
+ description?: ReactNode
+ errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
isEmphasized?: boolean
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
value?: string
}/@react-spectrum/s2:CheckboxProps CheckboxProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-controls?: string
aria-describedby?: string
aria-details?: string
aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
+ description?: ReactNode
+ errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isEmphasized?: boolean
isIndeterminate?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
validate?: (boolean) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: string
}/@react-spectrum/s2:RadioProps RadioProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
+ description?: ReactNode
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
onBlur?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
slot?: string | null
styles?: StylesProp
value: string
}/@react-spectrum/s2:SwitchProps SwitchProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ReactNode
defaultSelected?: boolean
+ description?: ReactNode
+ errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
inputRef?: RefObject<HTMLInputElement | null>
isDisabled?: boolean
isEmphasized?: boolean
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'native' | 'aria' = 'native'
value?: string
}@react-spectrum/switch/@react-spectrum/switch:Switch Switch {
UNSAFE_className?: string
UNSAFE_style?: CSSProperties
alignSelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'center' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'stretch'>
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
bottom?: Responsive<DimensionValue>
children?: ReactNode
defaultSelected?: boolean
end?: Responsive<DimensionValue>
excludeFromTabOrder?: boolean
flex?: Responsive<string | number | boolean>
flexBasis?: Responsive<number | string>
flexGrow?: Responsive<number>
flexShrink?: Responsive<number>
form?: string
gridArea?: Responsive<string>
gridColumn?: Responsive<string>
gridColumnEnd?: Responsive<string>
gridColumnStart?: Responsive<string>
gridRow?: Responsive<string>
gridRowEnd?: Responsive<string>
gridRowStart?: Responsive<string>
height?: Responsive<DimensionValue>
id?: string
isDisabled?: boolean
isEmphasized?: boolean
isHidden?: Responsive<boolean>
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginStart?: Responsive<DimensionValue>
marginTop?: Responsive<DimensionValue>
marginX?: Responsive<DimensionValue>
marginY?: Responsive<DimensionValue>
maxHeight?: Responsive<DimensionValue>
maxWidth?: Responsive<DimensionValue>
minHeight?: Responsive<DimensionValue>
minWidth?: Responsive<DimensionValue>
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
order?: Responsive<number>
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
right?: Responsive<DimensionValue>
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'aria' | 'native' = 'aria'
value?: string
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}/@react-spectrum/switch:SpectrumSwitchProps SpectrumSwitchProps {
UNSAFE_className?: string
UNSAFE_style?: CSSProperties
alignSelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'center' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'stretch'>
aria-controls?: string
aria-describedby?: string
aria-details?: string
+ aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
bottom?: Responsive<DimensionValue>
children?: ReactNode
defaultSelected?: boolean
end?: Responsive<DimensionValue>
excludeFromTabOrder?: boolean
flex?: Responsive<string | number | boolean>
flexBasis?: Responsive<number | string>
flexGrow?: Responsive<number>
flexShrink?: Responsive<number>
form?: string
gridArea?: Responsive<string>
gridColumn?: Responsive<string>
gridColumnEnd?: Responsive<string>
gridColumnStart?: Responsive<string>
gridRow?: Responsive<string>
gridRowEnd?: Responsive<string>
gridRowStart?: Responsive<string>
height?: Responsive<DimensionValue>
id?: string
isDisabled?: boolean
isEmphasized?: boolean
isHidden?: Responsive<boolean>
+ isInvalid?: boolean
isReadOnly?: boolean
+ isRequired?: boolean
isSelected?: boolean
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginStart?: Responsive<DimensionValue>
marginTop?: Responsive<DimensionValue>
marginX?: Responsive<DimensionValue>
marginY?: Responsive<DimensionValue>
maxHeight?: Responsive<DimensionValue>
maxWidth?: Responsive<DimensionValue>
minHeight?: Responsive<DimensionValue>
minWidth?: Responsive<DimensionValue>
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (boolean) => void
+ onClick?: (MouseEvent<FocusableElement>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
order?: Responsive<number>
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
right?: Responsive<DimensionValue>
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
+ validate?: (boolean) => ValidationError | boolean | null | undefined
+ validationBehavior?: 'aria' | 'native' = 'aria'
value?: string
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
} |
Closes #6192, closes #5548, related to #6151
This adds support for
<Text slot="description">and<FieldError />in individual checkboxes and switches, and description support for individual radios. Because this requires introducing another wrapper around the<label>elements we currently render, we are deprecating the existing components and introducingCheckboxField+CheckboxButton,RadioField+RadioButton, andSwitchField+SwitchButton. This way additional elements can be added outside the clickable element while still accessing the state (e.g. validation). In the next major we can perhaps renameCheckboxFieldback to justCheckboxfor example.Switch also now supports
isRequiredand other validation props like other form components. Although there are not many examples of required switches in the wild, it has been requested in the past, so we're adding it for parity.Test instructions
Test docs examples for Checkbox, CheckboxGroup, RadioGroup, and Switch in RAC and S2, and components that use these (e.g. Table selection checkbox).