You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We are currently developing an internal SSO form using React Aria for building our form components. We have encountered a specific issue with the RadioGroup and Radio components where the event bubbling seems to be stopped by the radio button logic. This is problematic for us as we intend to allow users to navigate to the next step in our form by pressing the 'Enter' key while a radio button is focused. However, the 'Enter' key event does not bubble up due to the internal handling in the Radio component, preventing our form from behaving as intended.
🤔 Expected Behavior?
Pressing the 'Enter' key while any Radio component is focused should allow the event to bubble up to parent elements where a handler could be triggered to navigate through the form.
😯 Current Behavior
The 'Enter' key event does not bubble up from the Radio components, preventing the form from navigating to the next step.
💁 Possible Solution
We are looking for a way to modify or override the default behavior to allow the event to bubble up, or perhaps a prop that could be passed to the Radio or RadioGroup components to control this behavior.
🔦 Context
Here what I found when investigated the Radio code:
The usePress hook from react-aria is being used in the Radio component. This hook handles the press
events (like mouse down, mouse up, key down, key up) and provides the pressProps that are spread onto the label
element in the Radio component.
The usePress hook calls preventDefault on the event object for 'Enter' key press to prevent the default
browser behavior. This is why the 'Enter' key press event is not bubbling up.
If you want the 'Enter' key press event to bubble up, you would need to modify the usePress hook to not call preventDefault on the 'Enter' key press event. However, this would require modifying the react-aria library,
which is not recommended.
A better approach would be to handle the 'Enter' key press event at the individual radio button level. You can do
this by adding an onKeyPress event handler to the Radio component and checking if the key pressed was 'Enter'.
functionRadio(props: RadioProps,ref: ForwardedRef<HTMLInputElement>){[props,ref]=useContextProps(props,ref,RadioContext);letstate=React.useContext(RadioGroupStateContext)!;letdomRef=useObjectRef(ref);let{inputProps, isSelected, isDisabled,isPressed: isPressedKeyboard}=useRadio({
...removeDataAttributes<RadioProps>(props),// ReactNode type doesn't allow function children.children: typeofprops.children==='function' ? true : props.children},state,domRef);let{isFocused, isFocusVisible, focusProps}=useFocusRing();letinteractionDisabled=isDisabled||state.isReadOnly;// Handle press state for full label. Keyboard press state is returned by useRadio// since it is handled on the <input> element itself.let[isPressed,setPressed]=useState(false);let{pressProps}=usePress({isDisabled: interactionDisabled,onPressStart(e){if(e.pointerType!=='keyboard'){setPressed(true);}},onPressEnd(e){if(e.pointerType!=='keyboard'){setPressed(false);}}});let{hoverProps, isHovered}=useHover({isDisabled: interactionDisabled});letpressed=interactionDisabled ? false : (isPressed||isPressedKeyboard);letrenderProps=useRenderProps({
...props,defaultClassName: 'react-aria-Radio',values: {
isSelected,isPressed: pressed,
isHovered,
isFocused,
isFocusVisible,
isDisabled,isReadOnly: state.isReadOnly,isInvalid: state.isInvalid,isRequired: state.isRequired}});letDOMProps=filterDOMProps(props);deleteDOMProps.id;return(<label{...mergeProps(DOMProps,pressProps,hoverProps,renderProps)}data-selected={isSelected||undefined}data-pressed={pressed||undefined}data-hovered={isHovered||undefined}data-focused={isFocused||undefined}data-focus-visible={isFocusVisible||undefined}data-disabled={isDisabled||undefined}data-readonly={state.isReadOnly||undefined}data-invalid={state.isInvalid||undefined}data-required={state.isRequired||undefined}><VisuallyHiddenelementType="span"><input{...mergeProps(inputProps,focusProps)}ref={domRef}/></VisuallyHidden>{renderProps.children}</label>);}
🖥️ Steps to Reproduce
Upon pressing the enter key, the console.log will output de "radio" but not the "div". Also, you have to click on the radio button and press enter log something.
"use client"import{Label,Radio,RadioGroup}from'react-aria-components';importCheckCircleIconfrom'@spectrum-icons/workflow/CheckmarkCircle';exportdefaultfunctionRadioGroupExample(){return(<divclassName="bg-gradient-to-r from-blue-300 to-indigo-300 p-2 sm:p-8 rounded-lg flex justify-center"><RadioGroupclassName="flex flex-col gap-2 w-full max-w-[300px]"defaultValue="Standard"><LabelclassName="text-xl text-slate-900 font-semibold font-serif">
Shipping
</Label><ShippingOptionname="Standard"time="4-10 business days"price="$4.99"/><ShippingOptionname="Express"time="2-5 business days"price="$15.99"/><ShippingOptionname="Lightning"time="1 business day"price="$24.99"/></RadioGroup></div>);}functionShippingOption({ name, time, price }: {name: string,time: string,price: string}){return(<divonKeyDown={// when the enter key is pressed, log the value of the radio button(e)=>{if((easunknownasKeyboardEvent)?.key==="Enter"){console.log("div",e);}}}><Radiovalue={name}onKeyDown={// when the enter key is pressed, log the value of the radio button(e)=>{if((easunknownasKeyboardEvent)?.key==="Enter"){console.log("Radio",e);}}}className={({ isFocusVisible, isSelected, isPressed })=>` group relative flex cursor-default rounded-lg px-4 py-3 shadow-lg outline-none bg-clip-padding border border-solid${isFocusVisible ? 'ring-2 ring-blue-600 ring-offset-1 ring-offset-white/80' : ''}${isSelected ? 'bg-blue-600 border-white/30 text-white' : 'border-transparent'}${isPressed&&!isSelected ? 'bg-blue-50' : ''}${!isSelected&&!isPressed ? 'bg-white' : ''} `}><divclassName="flex w-full items-center justify-between gap-3"><divclassName="flex items-center shrink-0 text-blue-100 group-selected:text-white"><CheckCircleIconsize="M"/></div><divclassName="flex flex-1 flex-col"><divclassName="text-lg font-serif font-semibold text-gray-900 group-selected:text-white">{name}</div><divclassName="inline text-gray-500 group-selected:text-sky-100">{time}</div></div><divclassName="font-medium font-mono text-gray-900 group-selected:text-white">{price}</div></div></Radio></div>);}
Version
1.1.1
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
Mac OS
🧢 Your Company/Team
Adobe/react-aria
🕷 Tracking Issue
No response
The text was updated successfully, but these errors were encountered:
I don't think you should do this. Enter is typically used to submit forms implicitly. You may confuse users by having Enter behave as a Tab depending on the context, in a form or out of one.
That said, I think we have a bug, I cannot implicitly submit from a RadioGroup.
See native works: https://jsfiddle.net/xc1j9tg0/
I altered the codesandbox to something similar to this fiddle, the submit is not called. This is probably related to stopping the key from bubbling. I thought we had an issue already open for this, but I couldn't find it. So I'll leave this one for now.
Provide a general summary of the issue here
We are currently developing an internal SSO form using React Aria for building our form components. We have encountered a specific issue with the RadioGroup and Radio components where the event bubbling seems to be stopped by the radio button logic. This is problematic for us as we intend to allow users to navigate to the next step in our form by pressing the 'Enter' key while a radio button is focused. However, the 'Enter' key event does not bubble up due to the internal handling in the Radio component, preventing our form from behaving as intended.
🤔 Expected Behavior?
Pressing the 'Enter' key while any Radio component is focused should allow the event to bubble up to parent elements where a handler could be triggered to navigate through the form.
😯 Current Behavior
The 'Enter' key event does not bubble up from the Radio components, preventing the form from navigating to the next step.
💁 Possible Solution
We are looking for a way to modify or override the default behavior to allow the event to bubble up, or perhaps a prop that could be passed to the Radio or RadioGroup components to control this behavior.
🔦 Context
Here what I found when investigated the Radio code:
The usePress hook from react-aria is being used in the Radio component. This hook handles the press
events (like mouse down, mouse up, key down, key up) and provides the pressProps that are spread onto the label
element in the Radio component.
The usePress hook calls preventDefault on the event object for 'Enter' key press to prevent the default
browser behavior. This is why the 'Enter' key press event is not bubbling up.
If you want the 'Enter' key press event to bubble up, you would need to modify the usePress hook to not call
preventDefault on the 'Enter' key press event. However, this would require modifying the react-aria library,
which is not recommended.
A better approach would be to handle the 'Enter' key press event at the individual radio button level. You can do
this by adding an onKeyPress event handler to the Radio component and checking if the key pressed was 'Enter'.
🖥️ Steps to Reproduce
Upon pressing the enter key, the console.log will output de "radio" but not the "div". Also, you have to click on the radio button and press enter log something.
Version
1.1.1
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
Mac OS
🧢 Your Company/Team
Adobe/react-aria
🕷 Tracking Issue
No response
The text was updated successfully, but these errors were encountered: