I'm trying to build a design-system in Typescript using React-Aria and I am having some trouble with the Radio component.
I tried to follow the example as much as I could but I ended up with : Argument of type 'null' is not assignable to parameter of type 'RadioGroupState'.
And I don't understand how to solve this issue, does someone have some advice for me?
Here's my code :
import { VisuallyHidden } from '@react-aria/visually-hidden';
import { useFocusRing } from '@react-aria/focus';
import { useRadioGroup, useRadio } from '@react-aria/radio';
import { useRadioGroupState } from '@react-stately/radio';
import { AriaRadioGroupProps } from '@react-types/radio';
import { AriaRadioProps } from '@react-types/radio';
let RadioContext = React.createContext(null);
interface RadioGroupProps extends AriaRadioGroupProps {
children: React.ReactNode;
}
interface RadioProps extends AriaRadioProps {
children: React.ReactNode;
}
function RadioGroup(props: RadioGroupProps) {
let { children, label, isDisabled, defaultValue } = props;
let state = useRadioGroupState(props);
let { radioGroupProps, labelProps } = useRadioGroup(props, state);
return (
<div {...radioGroupProps}>
<span {...labelProps}>{label}</span>
<RadioContext.Provider value={state}>{children}</RadioContext.Provider>
</div>
);
}
function Radio(props: RadioProps) {
let { children } = props;
let state = React.useContext(RadioContext);
let ref = React.useRef(null);
let { inputProps } = useRadio(props, state, ref);
let { isFocusVisible, focusProps } = useFocusRing();
let isSelected = state.selectedValue === props.value;
let strokeWidth = isSelected ? 2 : 2;
return (
<label
className={`${state.isDisabled ? 'cursor-not-allowed' : ''}`}
style={{ display: 'flex', alignItems: 'center' }}
>
<VisuallyHidden>
<input {...inputProps} {...focusProps} ref={ref} />
</VisuallyHidden>
<svg width={24} height={24} aria-hidden="true" style={{ marginRight: 4 }}>
<circle
cx={12}
cy={12}
r={8 - strokeWidth / 2}
fill="none"
stroke={isSelected ? 'red' : '#BBBBBB'}
strokeWidth={strokeWidth}
/>
{isSelected && (
<path transform="translate(5.5 5)" d={`M 4 3 A 1 1 0 0 0 9 11 A 1 1 0 0 0 4 3`} fill="#F70000" />
)}
</svg>
<div className={`${state.isDisabled ? 'text-grey-disabled cursor-not-allowed' : ''}`}>{children}</div>
</label>
);
}
export { Radio, RadioGroup };
I solved the problem this way:
RadioGroupState
from@react-stately/radio
.let RadioContext = createContext<RadioGroupState | null>(null);
null
possibility:let stateOrNull = useContext(RadioContext);
state
variable and casted it to theRadioGroupState
type:let state = stateOrNull as RadioGroupState;
CodeSandbox