tooltip div with ReactJS - javascript

objective
I have a div that I want to make act like a tooltip with reactjs.
HTML
<div>on hover here we will show the tooltip</div>
<div>
<div class="tooltip_custom">this is the tooltip!!</div>
</div>
I am used to angularjs using the ng-show with a condition on the <div> , I was wondering if there is such binding in reactjs , or else how can I do this functionality ?
Thanks

You can make your component to return the following markup
return (
<div>
<div onMouseOver={this.handleMouseIn.bind(this)} onMouseOut={this.handleMouseOut.bind(this)}>on hover here we will show the tooltip</div>
<div>
<div style={tooltipStyle}>this is the tooltip!!</div>
</div>
</div>
);
Where tooltipStyle is assigned like this:
const tooltipStyle = {
display: this.state.hover ? 'block' : 'none'
}
So tooltip depends on component state, now in handleMouseIn and handleMouseOut you need to change component state to make tooltip visible.
handleMouseIn() {
this.setState({ hover: true })
}
handleMouseOut() {
this.setState({ hover: false })
}
Here is working example.
You can start diving in React with this article: Thinking in React.

One option is just to do it in CSS. It's not quite as flexible, but with markup like:
<div className="tooltip-on-hover">Hover here</div>
<div className="tooltip">This is the tooltip</div>
You could do:
.tooltip {
...
visibility: hidden; /* Or display: none, depending on how you want it to behave */
}
.tooltip-on-hover:hover + .tooltip { /* Uses the adjacent sibling selector */
visibility: visible; /* Or display: block */
}
Example:
.tooltip { display: none; }
.tooltip-on-hover:hover + .tooltip { display: block; }
<div class="tooltip-on-hover">Hover here</div>
<div class="tooltip">This is the tooltip</div>
You could also nest the tooltip inside the element so you could use a normal descendant selector like .tooltip-on-hover:hover .tooltip. You could even use a ::before or ::after pseudo-element, there are guides around on how to do this.

I think whatever you want to show as tooltip, just add that to the "title" of the div where you want to show it.
Eg:
<div title="I am the tooltip text">I am the div where you should hover</div>
But if its a custom designed div then go as the answers given before.

Install npm package:
npm install react-tooltip
Usage:
import ReactTooltip from "react-tooltip";
<div data-tip="msg to show" data-for='toolTip1' data-place='top'>Tooltip</div>
<ReactTooltip id="toolTip1" />

You can also use React Mapple ToolTip which is easy to use and customize and also comes with predefined themes.
Disclaimer: I am the author of this library
reactjs-mappletooltip

You can use react-tooltip package. Super easy to use and handy also.
Installation: npm i react-tootip.
Example:
1. import it :
import ReactTooltip from "react-tooltip"
Include it in your component:
<div className="createContent">
**<ReactTooltip />**
<div className="contentPlaceholder">
add tool tip to your button/div or any element: data-tip="add tooltip message"
<button className="addSection" data-tip="add tooltip message" onClick={() => this.onAddChild()}>+</button>
package url: https://www.npmjs.com/package/react-tooltip

import Tooltip from "#material-ui/core/Tooltip";
const HtmlTooltip = withStyles((theme) => ({
tooltip: {
backgroundColor: 'rgba(255,250,228)',
color: 'rgba(0, 0, 0, 0.87)',
maxWidth: 400,
fontSize: theme.typography.pxToRem(12),
border: '1px solid #dadde9',
},
}))(Tooltip);
headerName: 'FEEDBACK',
field: "remarks",
flex: 0.30,
renderCell: (params: GridCellParams) => (
<Grid>
<HtmlTooltip title={params.value} placement="bottom">
<Typography style={{ color: "inherit", cursor: "pointer" }}>{params.value}</Typography>
</HtmlTooltip>
</Grid>
)

In case, if you are using react-bootstrap in your project, then use https://react-bootstrap.github.io/components/overlays/ Overlay with the tooltip.
MouseEnter and MoverLeave need to be used though.
<OverlayTrigger
placement="right"
delay={{ show: 250, hide: 400 }}
overlay={renderTooltip}>
<div>on hover here we will show the tooltip</div>
</OverlayTrigger>

Related

Convert from css to makestyle material UI

I want to add an iconButton and display a website preview when the mouse hover the help icon. I found something similar using css but I need to convert that to material UI.
This is the css code to be converted from this post How to show live preview in a small popup of linked page on mouse over on link?
.box{
display: none;
width: 100%;
}
a:hover + .box,.box:hover{
display: block;
position: relative;
z-index: 100;
}
This is what I have so far:
const HoverText = () => {
return (
<div className={classes.box}>
<iframe src="https://en.wikipedia.org/" width="500px" height="500px">
</iframe>
</div>
);
};
return (
<>
<IconButton size="large" color="inherit" onClick={() => window.open("https://en.wikipedia.org/", "_blank")}>
<HelpIcon className={classes.act} />
<HoverText />
</IconButton>
</>
);
Could you please help me to fix this:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
box: {
width: '100%',
display: 'none'
},
act: {
"&:hover + .box, .box:hover": {
display: 'block',
position: 'relative',
zIndex: 100
}
}
}),
);
Im expect to display a preview of a website page when mouse is over the icon.
You have to use the $ character when referencing another rule name. I changed a code a bit, use classes.act on IconButton (the hover effect will be better), and use the following:
const useStyles = makeStyles(() =>
createStyles({
box: {
width: 0,
height: 0,
display: "none"
},
act: {
"&:hover $box": {
display: "block",
zIndex: 100
}
}
})
);
Use $box instead of .box.
There is no box class generated when you compile your code (You can inspect your code and see what it compiles to). So the .box class selector does not work because there is no box class.
You should use $ to select another local rule or class within the same stylesheet. Read more.
"&:hover + $box, $box:hover"

Styling with dynamically used class names and attributes in JS(React)?

I wonder if there is a feasible way to implement something like that.
Say, I want to specify padding but I don't want to use inline styling and want to use classes instead. But I also don't want to specify all possible values in CSS.
Like I write:
<Container className="p25 m10" />
what can be rendered to the self-generated classes p25 and m10
<div class="p25 m10"/> /* Classes p25 and m10 are self-generated and have padding and margin */
or even
<Container p=25, m=10 />
rendered into the same or at least to
<div style="padding: 25px; margin: 10px"/>
I don't see that there is a way to auto-generate a css class. But,
this your first option, are classes that represent some kind of pure css style, what you can do is create a class like this:
.p25 {
padding: 25px;
}
<Container className="p25"/>
Your second option, are props that inside the functional component, through some logic, you will carry out the implementation, for example:
export default function Container({p, m}) {
return (
<div style={{padding: `${p}px`}, margin: `${m}px`}></div>
)
}
install tailwind and config manual stuff into config file.
module.exports = {
theme: {
extend: {
spacing: {
'25': '25px',
}
}
}
}
then use it this way
<div class="p-[25]">
<!-- ... -->
</div>

How to add hover css style with React.createElement

I'm creating a button with React.createElement:
React.createElement('button', {style: button.key === this.state.customBtnSelected ? customBtnSelected : customBtnUnSelected, onClick: () => {this.handleCustomBtnClick(i)} }, button.label)
So the one of the css styles is in the customBtnUnSelected variable.
But how do I add css classes for the hover state?
So far this isn't working:
const customBtnUnSelected = {
padding: 12,
textAlign: "center",
textDecoration: "none",
display: "inline-block",
fontSize: 12,
cursor: "pointer",
backgroundColor: "#CFD4DA",
border: "1px solid white",
&:hover: {
color: "#fff"
}
};
It's not possible to use the :hover, :after, or :before styling to an element, using inline styling.
The only way to achieve that is to use the <style> tag, or linking an external CSS file to your project.
To insert a style tag, you just place it somewhere in your app. It may be in one of your components, or in the root HTMl file, etc...
return (
<style>{`
.myButton {
padding: 8;
background: black
}
.myButton:hover {
background: grey
}
`}</style>
)
Then, you can just use the myButton class on the className prop of your button.
<button className='myButton'>Click</button>
or
React.createElement('button', {className: 'myButton'})
Regardless of using React.createElement or the JSX syntax, React doesn't support selecting pseudo elements with inline styling.
This question has a few answers with a lot more tips that might help you:
CSS pseudo elements in React

Filter issue while using Search/Filter logic - React Native

I am struggling with my React Native App!!!!
I have a simple Flatlist.
I have a TextInput that has a filter option.
Click inside the TextInput. A dropdown of filter appears.
Click on that Filter it appears inside the TextInput.
Need some help in styling this!!! It should look somewhat like this. If not to this extent at least a box around it is fine.
I tried it with a Button - React Native elements. It's so so so frustrating. I cannot use any 3rd party libraries (company policy).
TextInput Code:
<Icon type='materialicons' name='search' /> // search icon
<Button icon={<Icon name="check"/>}. //my attempt to create a button around the filter
type='clear' title ={val}
onPress={()=>{this.handleFilterIcon(false); this.setFilt(false)}}/>
<TextInput // Text Input
value={value}
placeholder='Search Here...'
onChangeText={(text)=>{this.handleSearch(text, true);this.renderDropDown(false)}}
onTouchStart={()=>{this.setTempNotifications();this.renderDropDown(true)}}
style={{ height: 40, flex: 1}}
autoCapitalize='none'
selectTextOnFocus={true}
label='input'
/>
<Icon type='materialicons' name='cancel' onPress={()=>{} /> // Clear Icon
<Button title='Cancel'
buttonStyle={{backgroundColor:'#D3D3D3', borderColor: 'grey', borderRadius: 6 , borderWidth: 1, height: 40}}
onPress={()=>{} /> // Cancel button
Anyone please tell me the most efficient way to do this!!!
The only way I'm seeing is, since you don't have to use third party libraries is this:
Create a an empty label next to the input. Wrap these two with a div with position:relative
As soon as input is entered, put the same text in this label. Customise this label with styling: position:absolute;background:grey...
Just to give you some idea, here's an implementation in JQuery. You have to take this forward and ask specific question where you're struggling.
function inputChange(val){
$('label').text(val);
$('input').val("");
}
label{
border:1px solid;
border-radius: 5px;
position: absolute;
background: grey;
left:2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input type="text" onchange="inputChange(this.value)"/>
<label></label>
</div>
In React the same implementation could look something like this. You can create a file with this implementation, import in your App.js and see. Take this idea fowrward and change the styling and behaviours as per the need.
import React, { Component } from 'react';
class CustomInputTextstyling extends Component {
constructor(props) {
super(props);
this.state ={
inputText: ""
}
}
handleInputChange(e){
this.setState({inputText: e.target.value});
}
render() {
const wrapperDiv = {
position: 'relative'
}
const label = {
border:'1px solid',
borderRadius: '5px',
position: 'absolute',
background: 'grey',
left:'2px'
}
return (
<div style={wrapperDiv}>
<input type = "text" onBlur = {this.handleInputChange.bind(this)}></input>
<label style={label}>{this.state.inputText}</label>
</div>
);
}
}
export default CustomInputTextstyling;

React: Resizing a div including handlers, different cursors i.e ns-resize - no jquery

I am looking for an easy way of allow a user to resize a div using handles and all relevant cursors. I see lots of examples using jquery but I would like to use it in react and jquery isn't required.
Does anyone know a easy way of doing this ? I presume pure js, css. I don't really want to use a react component for this, as I need to enable resizing on standard divs.
Of course it is for use with reactjs, is there a more modern way of doing this without jquery ?
** EDIT **
These are the cursors that could be used for each resizable point
e-resize ne-resize n-resize nw-resize s-resize se-resize
w-resize sw-resize
You can only with CSS, resize property allows you to make that!
.resize {
border: 1px solid black;
overflow:auto;
}
.resize.horizontal {
resize: horizontal;
}
.resize.vertical {
resize: vertical;
}
.resize.both {
resize: both;
}
.wrap {
max-width: 80%;
}
<div class="wrap">
<div class="resize horizontal">Resize me!</div>
<div class="resize vertical">Resize me!</div>
<div class="resize both">Resize me!</div>
</div>
Requirements
overflow different than visible (initial) is required and you can apply it to all elements whos overflow is setted with auto, scroll and hidden.
I call this property marvellous!
Heres an example of a great solution using react-resize-panel library
https://www.npmjs.com/package/react-resize-panel
Put anything you want to show inside the divs, you can customize the handler too.
import ResizePanel from "react-resize-panel";
...
<div style={{
width: '80%',
height: '500px',
border: '1px solid black',
display: 'flex',
flexDirection: 'column'}}>
<ResizePanel direction='s' style={{backgroundColor: 'black', height: '50%'}}>
<div style={{backgroundColor: 'orange', height: '100%'}}>panel</div>
</ResizePanel>
<div style={{backgroundColor: 'purple', flexGrow: '1'}}>panel</div>
</div>
...
Hope this can help someone else
A few days ago I wanted to build something like this but with 2 div elements.
using resize property from css made it's width 0 when there are multiple elements so I tried javascript.
I saw an example using onMouseMove event but there are many problems with this example so I made a new sandbox in which I use the onDarg event.
Here is the important code:
const dragHandler = useCallback(
(e) => {
const w =
((e.clientX -
e.currentTarget.parentElement.parentElement.getBoundingClientRect()
.left) /
e.currentTarget.parentElement.parentElement.getBoundingClientRect()
.width) *
100;
if (w > 0 && w !== width) {
setWidth(w);
}
},
[width]
);
and
<Box width={width} />
<div
draggable
onDrag={dragHandler}
className="flex justify-center items-center p-1 h-full bg-slate-800 cursor-col-resize"
>
<div className="w-1 border-x border-white h-1/6" />
</div>
<Box width={100 - width} />
Hope it helps \(^_^)/

Categories