React pass onMouseHover to Children component - reactjs

I am implementing a small react component called react-hover in it's V2 version.
This lib just simply enable user to define their trigger and hover component and make the hover component appear when mouse hover on trigger component.
<ReactHover
options={optionsCursorTrueWithMargin}>
<ReactHover.Trigger>
<TriggerComponent />
</ReactHover.Trigger>
<ReactHover.Hover>
<HoverComponent />
</ReactHover.Hover>
</ReactHover>
Now I am facing an issue of passing the onMouseHover events to the children component in tigger component:
render () {
return (
<div
onMouseOver={this.onMouseOver.bind(this)}
onMouseOut={this.onMouseOut.bind(this)}
onMouseMove={this.onMouseMove.bind(this)}
onTouchStart={this.onTouchStart.bind(this)}
onTouchEnd={this.onTouchEnd.bind(this)}
>
{this.props.children.props.children}
</div>
)
}
Because only the children component can tigger the hover component, but in above implementation, it is binding the listeners to the parent div, so I met the issue that parent div's css width is more than the childen's width, so when mouse is on the div ( not in the children) the hover component show up. But I cannot control the children component's inner code as it is passed in as children.
I am just wondering how to tackle this issue?
The example code is here.
The place where bind the mouse event is here
Just wondering what's the solution for this?
how to bind those events to the children component when cannot put code in children component.
Below is showing when mouse outside of trigger component still can trigger the hover component.

Just resolved by add ref to the container and retrieve Children's width:
let childStyles = this.refs.triggerContainer.children[0].style
and apply to the current parent container.
check this code

Related

ReactJS: Disable mouse events in child components of parent

I have a components hierarchy like this:
<parent>
<someWrapper1>
<child>
<child>
<someWrapper2>
<child>
<child>
Each child component handles a bunch of mouse events on it's own where some are D3 wrappers managing onDragStart and onClick mouse events.
I am looking for a way to disable all mouse events in the <someWrapper1/>, <someWrapper2/> components, as well as in the <child/> components, based on the parent's component state.
One solution, would be to pass the prop of disable to the wrapper components, and to also pass those down to each child and then into
each handler to disable or enable mouse events. I want to avoid this as it will be hard to maintain.
I am looking for a nicer solution where I can disable all mouse events in all components from the parent component.
Thanks!
If I understand correctly, you're looking to disable mouse events on specific sub-trees of your DOM. In that case, you could use the CSS pointer-events: none; rule to achieve this.
For example, to restrict mouse events on an element/component and it's children, you could create a style object with a pointer-events key and none value, and apply this to <someWrapper1> components to dynamically enable/disable mouse events on those components (and their descendants):
/* Your components render method */
render() {
/* Acquire the disableEvents value from state, etc */
const disableEvents = true;
/* Dynamically compute style for wrapper components
to control mouse interactivity */
const wrapperStyle = {
"pointer-events": disableEvents ? "none" : "unset"
};
/* Apply dynamic styles to wrappers. When disableEvents
is true, mouse events will be disabled on someWrapper1
and child descendants */
return (<parent>
<someWrapper1 style={wrapperStyle}>
<child />
<child />
</someWrapper1>
<someWrapper1 style={wrapperStyle}>
<child />
<child />
</someWrapper1>
</parent>)
}

Triggering a passed-down event inside custom MenuList in React-Select

I want to open a modal which exists in the parent component from a button inside the MenuList of react-select. I created a custom MenuList with my button and passed it to react-select as <Select components={{ MenuList }} />. I am not sure how to handle the click event of that button in order to trigger my modal.
My code is here: https://codesandbox.io/s/rllz53k8ln
Inside your props on MenuList component, you have an object called "selectProps". Whatever custom prop you pass down to Select component itself will be accessible through that "selectProps" object.
Here's the code: https://codesandbox.io/s/9325wk90pr

What is causing my component to unmount?

I'm making an app where I have an Overlay component and a Map component rendering behind it just like this:
<div>
{showOverlay && <Overlay />}
<Map /> // this component should mount once
</div>
The overlay is shown to let the map load underneath but when I remove the Overlay (set showOverlay to false here) the Map component re-load.
At first I thought the Map component was just re-rendering, but after some digging I discovered that the component was actually re-mounting.
If I log in the componentWillMount, componentWillUnmount and render methods, the log appear in that order (which seems contradictory)
render
willUnmount
willMount
The parent does not re-mount, only the Map component do.
The Map component just render a div that reference a mapbox-gl-js map (like this https://gist.github.com/tristen/5c4b346ae38892f732504e6785d87057#file-map-js)
What can cause my component to re-mount itself like that ?
Thanks !

Adding button text / label inside SpeedDialAction - Material-UI v1 / React

I am trying to add labels to nested <SpeedDialAction /> components, and have button text displayed next to icons like so:
but it seems like children do not get rendered:
...
<SpeedDialAction
key={action.name}
icon={action.icon}
tooltipTitle={action.name}
onClick={this.handleClick}
>
Foo
</SpeedDialAction>
...
I also tried using the ButtonProps prop as listed in the docs but that did not do the trick either.
I take a look at the SpeedDialAction source code https://github.com/mui-org/material-ui/blob/6f9eecf48baca339a6b15c5fcfb683cba11e4871/packages/material-ui-lab/src/SpeedDialAction/SpeedDialAction.js
The title of Tooltip only shows on hover, but it can be easily done by changing default state to true, eg: state={ tooltipOpen: true } in SpeedDialAction.js file.
However, Tooltip component in SpeedDialAction has no reference, so there is no easy way to setState from outside.
The easiest solution is to create a custom SpeedDialAction component.
SpeedDialAction component contents only Tooltip and Button, which it's hard to modify.
There is the codesandbox https://codesandbox.io/s/9zpyj4o0zo
You can simply add SpeedDialAction.js file to your project.
Update:
Removed onClose event in Tooltip in codesandobox. Fixed the problem where title disappear after click.

Disabling unfocused scenes in react-native-router-flux

I am using redux to change style of my custom NavBar component. My NavBar is not part of Router neither scenes, I introduce them in direct scene JSX. Example JSX from my scene component:
<View style={{ flex: 1 }}>
<NavigationBar /> <--- My custom NavBar
{ this.renderScreen() }
<Tabulator
tabs={TABS}
style={styles.navbar}
listenTo='screen'
/>
</View>
In the second scene I have a ScrollView which is dispatching actions when I scroll the view. For an example, I am dispatching opacity of the NavBar while you scroll down and change its title after a certain y value. The problem is, when I scroll the view and before it can stop I go back from the second scene to the first one, the ScrollView did not yet stopped scrolling so it dispatches few more actions.
Is there a way to disable the scene?
I have noticed that this gets called while the scene is alive during the scene change animation until componentWillUnmount() gets called.
I tried to put a reducer into the router and dispatching an action that the scene switching is in progress. I check if the action type is anything else than REACT_NATIVE_ROUTER_FLUX_FOCUS then the changing is in progress. so while it is true the action changing the NavBar is ignored, but this sets false before it gets to unmounting.

Resources