React-Sidebar: Button is unclickable when moved outside props.children - javascript

I'm trying to modify the first example given in the react-sidebar documentation by moving the location of the button outside of the props.children. When I do this, the button becomes unclickable. The button doesn't not just do anything, it actually can't be clicked.
It seems like the z-index from the sidebar is taking up the full screen even when it is collapsed, but when i set the button's z-index to 3 it is still unclickable.
render() {
return (
<Sidebar
sidebar={<b>Sidebar content</b>}
open={this.state.sidebarOpen}
onSetOpen={this.onSetSidebarOpen}
styles={{ sidebar: { background: "white" } }}
>
<button onClick={() => this.onSetSidebarOpen(true)}>
Open sidebar
</button>
</Sidebar>
);
}
My non-working modification:
render() {
return (
<div>
<Sidebar
sidebar={<b>Sidebar content</b>}
open={this.state.sidebarOpen}
onSetOpen={this.onSetSidebarOpen}
styles={{ sidebar: { background: "white" } }}
/>
// Moved button out of here
</Sidebar>
<button onClick={() => this.onSetSidebarOpen(true)}>
Open sidebar
</button>
</div>
);
}

This is because react-sidebar has an overlay which is covering the entire screen and the button is falling beneath it, because of which you can't click the button. Just give the button position: absolute and z-index: 4 or so and it will become clickable and will work.

The given answer doesn't work. What worked for me was setting the overlay's height and width to zero. Using Developer Console, you can find the CSS selector for the overlay, which, for me was #gatsby-focus-wrapper > div:nth-child(1). So, the code that fixed the issue was -
#gatsby-focus-wrapper > div:nth-child(1){
height: 0;
width: 0;
}

Related

Stopping propogation of button that contains tooltip with link not working on Button

I am using the Material UI Button Component and in the button, there is text. And right next to that text, I have a tooltip. And in that tooltip, there is a link to an article. The idea is that I want the user to have a chance to be able to click the 'read more' link inside the tooltip before clicking the actual button. The issue is that when clicking the 'read more' link that is inside the tooltip, it actually clicks the button instead. I have tried to use the e.stopPropagation event that supposedly stops the component from bubbling to other elements. But it still doesnt prevent the button from being clicked instead of the 'read more' link that is within the tooltip. Please see my code below:
render() {
const { buttonStyleOverride, classes } = this.props;
const { buttonDisabled } = this.state;
return (
<Button
name="buyItem"
variant="outlined"
style={buttonStyleOverride}
className={classes.button}
color="primary"
disabled={buttonDisabled}
onClick={
this.addItems,
e => e.stopPropagation()
}>
Buy Pikafoods
<TooltipIcon
title="You can read more about pikafoods here."
learnMoreLink="https://pokemon.com/articles/pikafoods"
style={{ position: 'relative', top: '-2px' }} />
</Button>
);
}
}
It's really strange a clickable tooltip inside a button, not very user friendly.
However you have to stop the propagation in the tooltip event, not in the button, like this:
import { Button } from "#material-ui/core";
import AccessibilityIcon from "#material-ui/icons/Accessibility";
export default function App() {
return (
<div className="App">
<Button
name="buyItem"
variant="outlined"
color="primary"
onClick={(e) => console.log("button")}
>
Buy Pikafoods
<AccessibilityIcon
onClick={(e) => {
console.log("tooltip");
e.stopPropagation();
}}
/>
</Button>
</div>
);
}

Prevent moving text elements on hover which is +1px font size

I have a row with text elements, in this case they are named "categories", any category that is on hover gets added a class that has font-size 1px bigger than non hover. Font size of my category may be diffrent (all categories have the same font but in config it can be changed) and comes from outside config.
const currentCategoryStyle = {
fontSize: `${parseInt(singleCategory['font-size'].replace('px', '')) + 1}px`,
};
<div className="categories-container d-flex">
{categories.map(category => (
<div
className="single-category"
onMouseEnter={() => {
setCategoryHover(category.id);
}}
onMouseLeave={() => {
setCategoryHover(null);
}}
style={{
...(
categoryHover === category.id &&
currentCategoryStyle),
}}
>
{category.name}
</div>
))}
</div>
But the problem is, that every element moves a bit, when I hover one category, of course because it gets bigger. My question is, what can I do to prevent this? Margin, padding doesn't really work here, any ideas?

How to make Show more / Show less toggle button for API dynamic data in paragraph or simple text in REACT?

My requirement is that, I have multiple tabs on web page and in each tab data come from API. The data is dynamic and daily changing. I have a div say a rectangular box of fixed height and below it, there is button "Read more / Read less".
If data contained in that rectangular box exceeds the height of that box, "Read more" button will be shown, otherwise if the data size is small, button is invisible.
I have done most of these things and have two problems with my code is that,
Sometimes data shown as partial data i.e. when data size is big, part of the data is hidden back of toggle button and at the same time bottom text line is partially hidden behind box or button.
after clicking read more I can scroll the data up & down. But if I click "Read less" button on scrolled down condition, that div locks over there and scrolling stops. I want that, I may be anywhere on the scrolling page and if I click "Read less", the page should automatically scrolled to top and scrolling should stop.
I am attaching my sample code. I have removed some of the classNames for security issue, please help for above two points..
<div id="tab_number" >
<div className="">
<div className=''>
<div ref={`showTheScrolling`} className={`${Theme} parent`} style={{overflow:"hidden"}}>
<h3>Tab Heading</h3>
{
<div className="content" style={{height:"475px"}} dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}></div>
}
</div>
{this.state.thisData.tabData.length > 1500 ?
<div>
<div ref={`buttonShowMore`} className="">
<a id="ClickForShowMore" onClick={() => { this.toggleShow_more() }}><b>Show More</b></a>
</div>
<div ref={`buttonShowLess`} className=" showButton_hide">
<a id="ClickForShowMore" onClick={() => { this.toggleShow_less() }}><b>Show Less</b></a>
</div>
</div> : ""
}
</div>
</div>
and two functions above render() section
toggleShow_more = () => {
console.log(this.refs)
this.refs[`showTheScrolling`].classList.add('filterscroller');
this.refs[`buttonShowMore`].classList.add('showButton_hide');
this.refs[`buttonShowLess`].classList.remove('showButton_hide');
}
toggleShow_less = () => {
console.log(this.refs)
this.refs[`showTheScrolling`].classList.remove('filterscroller');
this.refs[`buttonShowMore`].classList.remove('showButton_hide');
this.refs[`buttonShowLess`].classList.add('showButton_hide');
this.refs[`showTheScrolling_${id}`].scrollTo({top: 0, behavior: 'smooth'});
}
For above first problem, we can use splitString(). Here we count up to 300 characters, if count is more, then we check first 50 words and show them in small window followed by toggle button will be provided for complete view.
If character count is less than 300, no toggle.
So, here the toggle window size is dynamic. It depends on characters or words count and it is changing along font size. The problem of partial viewing text behind some other div, box or button can be easily solved here.
{
// if tabData character length > 300 then
this.state.thisData.tabData.length > 300 ?
<div>
{this.state.readMore ?
<div className="your-classname" style={{ margin: "20px" }}
dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}>
</div>
:
<div className="your-classname" style={{ margin: "20px" }}
dangerouslySetInnerHTML={{ __html: this.splitString(this.state.thisData.tabData, " ", 50) }}>
</div>
}
<div>
<a className="your-classname2" style={{ }}
onClick={() => this.toggleReadMore()}>
{this.state.addRead ?
// if you are working with mobile view also, the for css adjustment select appropriate class
<div className={this.props.isMobileView ? "selectclass-if-isMobileViewTrue":"selectclass-if-isMobileViewFalse"}
>READ MORE
</div>
</React.Fragment>
:
<React.Fragment>
<div className={this.props.isMobileView ? "selectclass-if-isMobileViewTrue":"selectclass-if-isMobileViewFalse"}
>READ LESS
</div>
</React.Fragment>}
</a>
</div>
</div>
:
// if tabData character length < 300 then
<div className="your-classname" style={{ margin: "20px" }}
dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}>
</div>}

Putting a div inside a link - area still clickable outside div

I put a div inside an a tag with an intent that only when I hover on the area occupied by the div, I will get the hand cursor.
But it has a strange behavior.
You can see that the div has fixed dimensions (red border).
But even if I move the mouse outside the div, still the hand cursor appears.
Why?
Like I said I basically want only the area inside the red border to be clickable.
Here is the code:
const AppCustomIcon = (props) => {
return (
<a target="blank"
href={props.url}>
<div style={{
height: 100,
width: 100,
display: "flex",
flexDirection: "column",
border:"1px solid red",
alignItems: "center"
}}>
<IconButton
style={{marginRight: 10}}
onClick={props.handleClick}
>
{props.icon}
</IconButton>
<Typography variant={"body1"}>{props.text}</Typography>
</div>
</a>
)
}
Anchor tag a by default is display: inline.
If you are applying styles to an element that contains flow elements or any other elements that are represented in CSS as display: block, you should set the itself to a proper block container type such as block or inline-block for its layout to work as intended.

<Fade> in material-ui just disables the visibility of the component . How to get the fade effect and actually hide the component ?

I am using component of material-ui from material-ui.
<Fade in={!randomizeFlag}>
<Grid>
<FormControlLabel control={<Switch onChange={this.handleStartValueFlag} ></Switch>} label="Start Value"></FormControlLabel>
<TextField type="number" label="Starting Value" value={startValue} onChange={this.handleStartValueChange} />
</Grid>
</Fade>
I want to completely hide the element Grid when the component fades out but it only disables the visibility of the component and takes up the same space( looks empty) in the DOM .How do i make the element hide after fading it using <Fade>
<Fade in={!randomizeFlag} unmountOnExit={true}>
...
</Fade>
http://reactcommunity.org/react-transition-group/transition#Transition-prop-unmountOnExit
By default the child component stays mounted after it reaches the 'exited' state. Set unmountOnExit if you'd prefer to unmount the component after it finishes exiting.
Hiding element completely will introduce complexity since now you have to also unhide the element when Fade begins. That may interfere with fade effect.
With that said, you have few options:
Use CSS attribute selectors to apply styles:
div[opacity=0] {
display: none;
}
div[opacity=1] {
display: block;
}
Use react-transition directly (since that is what Fade uses): https://reactcommunity.org/react-transition-group/transition
import Transition from 'react-transition-group/Transition';
const duration = 300;
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
}
const transitionStyles = {
entering: { opacity: 0, display: 'none' },
entered: { opacity: 1 , display: 'block'},
exited: { opacity: 0, display: 'none'},
};
const Fade = ({ in: inProp }) => (
<Transition in={inProp} timeout={duration}>
{(state) => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
I'm a fade Transition!
</div>
)}
</Transition>
);
Use Fade and pass handlers to Transition, like onExited and set desired states in there. Fade will simply pass extra props to root Transition element so this may work. The only caveat is that you'd be triggering a setState or similar post render phase which can get tricky.
enclose your custom components in divs or some html element and it should work just fine
<Fade in={!randomizeFlag}>
<div>
<Grid>
<FormControlLabel control={<Switch onChange=
{this.handleStartValueFlag} ></Switch>} label="Start Value">
</FormControlLabel>
<TextField type="number" label="Starting Value" value=
{startValue}
onChange={this.handleStartValueChange} />
</Grid>
</div>
</Fade>
Based on #Mrchief answer I got an idea for using style attribute on Fade element:
<Fade in={!randomizeFlag} style={{display: randomizeFlag ? 'none' : 'block'}}>
...
</Fade>

Categories

Resources