React: Prevent Right Click from focusing an otherwise focusable element - reactjs

I know this seems simple, and the first instinct is going to be to suggest something like preventDefault in mousedown event. That is not what this question is.
In React, I just want to have an input that when Left Clicked receives its focus as normal, and when Right Clicked does not receive focus.
I can find no combination of event handlers or event manipulation that will allow this (in chrome at least). I'm tempted to put event handlers outside of the React DOM and get surgical with disabling higher up in the capture phase before react gets involved, but I'm just hoping I'm missing something and somebody can see something obvious I'm missing.
Here's various combinations of "everything" I've thrown at it. Synthetic event standard prevention, nativeEvent prevention, every variation of capture and bubble phase, etc. Event with all of the event handlers below, I can prevent Left Click from setting focus, but still Right Click sets focus on the input.
//React v16.12.0
function killEvent (e: React.SomeEvent<HTMLInputElement>): void {
e.nativeEvent.stopImmediatePropagation();
e.nativeEvent.preventDefault();
//[Neither above nor below seems to work]
e.preventDefault();
e.stopPropagation();
}
<input
onContextMenuCapture={killEvent}
onContextMenu={killEvent}
onClick={killEvent}
onClickCapture={killEvent}
onAuxClick={killEvent}
onAuxClickCapture={killEvent}
onPointerDown={killEvent}
onPointerDownCapture={killEvent}
onMouseDownCapture={killEvent}
onMouseDown={killEvent}
onFocusCapture={killEvent}
onFocus={killEvent}
/>

here is my solution
Capture on mouse down
<input onMouseDown={this.killEvent} />
then check which button is clicked
killEvent = e => {
if (e.nativeEvent.which === 3) {
e.nativeEvent.preventDefault();
}
};

Related

React-Tabs and React-Selection: Tabs Steal Focus From Select

How can I prevent the autofocus problem after tab is clicked? For example, when I clicked the tab and I scrolled down to the different div with selection, I opened and chose the options from selection. The focus kept returning to the tab that I clicked.
Undesired behavior
Desired behavior
Please let me know if this is something you can come up with solution to this problem.
It's hard to tell what exactly your problem is without seeing code, but you can control focus state using ref and accessing targets with refs. i.e.
const ref = React.useRef()
const toggleFocus = () => ref.current.focus()
return <input ref={ref} ... />
So, on open of a new tab, you could call "toggleFocus" (or whatever you call it) to focus the particular input you want to focus.
Hope that helps?

In onMenuClose or onBlur event of react-select identify whether event is triggered by option selection or the blur

In react select onBlur event or onMenuClose event is triggered when user selects the option or blur (click outside of the control).
So I want to perform the business logic on blur event if user has not selected an option.
In other words I want to know how blur event is triggered.
onBlur event is triggered when the focusable HTML Element loses focus. Maybe it's easiest to see if select option was changed? Don't know how your implementation looks though but maybe this will help you.

Reactour and focus issues on re-render

The Scenario
I am using the Reactour library to create a guided tutorial on my website. The library allows me to interact with highlighted components, which is the desired behavior. However, my input boxes have a onBlur attribute that updates the state in a parent component, thus re-rendering the child (component where the input boxes are).
The Issue
The problem is that this re-render is messing up the focus and the user is not able to "tab" between fields (when the tutorial is open). It seems that the Reactour component is receiving the focus after the re-render, even though they have a tabIndex="-1" set by default in their component.
My Approach
I tried to set explicit tabIndex properties, but that didn't work.
I thought about having an onKeyDown listener, check if the pressed key is tab and "manually" control the focus between fields, but that seems too hacky and messy, considering I have a lot of fields in my form.
I made a CodeSandbox here to reproduce the bug. You will notice that you can tab between inputs when the Tutorial is closed, but clicking the "Start Tour" button will mess the tabIndex behavior.
Any ideas?
Just for reference, this seems to be an issue with Reactour and it was logged here. Hopefully, it will be fixed soon.
For now, as a workaround, my solution was to manually set the tabIndex of Reactour components during initialization:
setTimeout(() => {
const elements = document.querySelectorAll("#___reactour button");
elements.forEach((el) => (el.tabIndex = -1));
}, 100);
The timeout is necessary since it takes a little bit for the elements to show up in the screen.

React efficient way to bind event to many dom elements

Because we add onClick handlers directly to components... eg:
<button onClick={dosomething}>Click</button>
Is there an efficient way to do this (not adding an onClick to every element) when we're dealing with dozens of elements ?
For example, in my backbone apps I would just apply a handler to a class:
events:
'click .someclass': 'doSomething'
The backbone way seems much cleaner and easier to manage. Is there a way to emulate this behavior with React Components?
To add some perspective, I have say a dozen or more form elements that when any of them are changed, I want to potentially runs some logic. They could be text boxes, radio buttons, etc.
This optimization is not needed. It would if you were coding in other libraries like jQuery, but React does this automatically for you.
I quote:
Event delegation: React doesn't actually attach event handlers to the nodes themselves. When React starts up, it starts listening for all events at the top level using a single event listener. When a component is mounted or unmounted, the event handlers are simply added or removed from an internal mapping. When an event occurs, React knows how to dispatch it using this mapping. When there are no event handlers left in the mapping, React's event handlers are simple no-ops. To learn more about why this is fast, see David Walsh's excellent blog post.
Seen here: https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html
You can apply the event handler to a common parent element instead and handle the event there:
<form onChange={this.handleChange}>
{/* ...form elements... */}
</form>
...where the event handler determines what to do based on the event object's .target:
handleChange(e) {
this.setState({[e.target.name]: e.target.value})
}
As a live example, I have an <AutoForm> component which uses this technique to render a <form> which handles extracting data from changed fields and the submitted form for you.

AngularJS analogue to jQuery preventDefault for keydown?

I need the browser to respond to keydown arrow events in focused scrollable boxes.
Here is a Plunker to show what I mean
http://plnkr.co/edit/Okch5dEByFkueJl0DmwG
Even if I tell the event to stop propagating with event.stopPropagation()
and make the event handler return false the box keeps scrolling on keydown.
Unless I'm mistaken as far as what you're looking for, you should just be able to change your
event.stopPropagation()
back to
event.preventDefault()
and it will work as desired.

Resources