Background using props in react.js - reactjs

Adding background by passing a variable in the input i.e validUrl. Anyone let me know if this background property works. Also imported both valid and invalid image.
background: ${ props => props.validUrl ? "url(${valid}) no-repeat left 10px center" : "url(${invalid}) no-repeat left 10px center" };

Write it like this using Template literals:
background: props.validUrl ? `url(${valid}) no-repeat left 10px center` : `url(${invalid}) no-repeat left 10px center`
Update:
Stories storiesOf("URLField", module) .add("default", () => (
<ThemeProvider theme={theme}>
<URLField validUrl={true} />
</ThemeProvider> )
)
const URLField = ({validUrl}) => (
<Wrapper>
<Urlwrapper>
<Input validUrl={validUrl} />
<Text>{urlDescription}</Text>
</Urlwrapper>
</Wrapper>
);

This is how it would be done as we need to pass the variable in outer wrapper. If its defined in the input then the styles according to property needs to be defined in input.js from where it is called. Updated code is as follows:
const URLField = ({ validUrl}) => (
<Wrapper validUrl={validUrl}>
<Urlwrapper>
<Input />
<Text>{domain}</Text>
</Urlwrapper>
</Wrapper>
);

Related

How do I add style inline the color code which I m getting from an array of object

Suppose my array of object is like this ms=[{id : 1 , Name : a , color : #333} {id : 2 , Name : b , color : #666} {id : 3 , Name : c , color : #ddd}]
Now my return in functional component
ms.map((eachname, index)=>
{
<div classname = mainbloc>
<div classname = insideblock style=.
{{borderRight: 1px solid ###}}>
{eachname.Name}
</div>
</div>
})
I want to add the color of each object in the border right ### place
Use template strings to embed javascript expressions or values between strings. You can do something like this.
ms.map((eachname, index) => (
<div classname="mainblock" key={index}>
<div
classname="insideblock"
style={{ borderRight: `1px solid ${eachname.color}` }}
>
{eachname.Name}
</div>
</div>
));
More information on template string:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
In case, for some reason, you don't want to use template strings you can use:
style={{
borderRightWidth: 1,
borderRightWidth: 'solid',
borderRightColor: eachname.color,
}}
You can also use styled components if you don't want to use inline styling and make component more reusable and readable. More information Styled components
import styled from 'styled-components'
const StyledDiv = styled.div`
borderRight: ${props => props.color}
`
ms.map((eachname, index) => (
<div classname="mainblock" key={index}>
<StyledDiv color={eachname.color}>
{eachname.Name}
</StyledDiv>
</div>
));

Children component height received as a prop from Parent component is not set

I want to make a child component height equal to parent component. To get parent height I use useRef and useEffect hooks, like below:
const [height, setHeight] = useState(0);
const ref = useRef();
useEffect(() => {
setHeight(ref.current.clientHeight);
});
When I console.log(height) it shows me actual height of the parent and typeof height is number.
This is how it's rendered:
<StyledTableHeader
key={idx}
isSorted={column.isSorted}
key={column.id}
{...column.getHeaderProps({})}
style={{
whiteSpace:
!matches && 'unset',
}}
ref={ref}
>
{matches ? (
<RenderDesktopVersion
column={column}
idx={idx}
/>
) : (
<RenderMobileVersion
column={column}
idx={idx}
height={height}
/>
)}
</StyledTableHeader>
And this is how it looks in Styled Components:
export const StyledHeaderWrapperMobile = styled.div`
display: flex;
flex-direction: column;
height: ${(props: any) => props.height};
`;
I want to use this code only for mobile version, where header of one column is driving height of all headers, and then all children components updates their header accordingly.
In the picture below You can see that header "status" don't fill full parent, console.log shows height of 93, and 93 is the height of the header one to the right ( the highest one )
[![enter image description here][1]][1]
Thanks for helping and showing where I do wrong

Add Space Between Row Elements in React BootStrap

I am new to React and react-bootstrap. I have a Row component and would like spacing between the top of the screen and also between the individual row elements. I am currently just editing its CSS but heard that it may be bad to mess with the CSS of frameworks?
const Styles = styled.div`
.background {
background: url(${backgroundImage}) no-repeat fixed bottom;
background-size: cover;
height: 100vh;
position: relative;
}
#row {
position: relative;
top: 200px;
}
`;
class Signup extends React.Component {
render() {
return (
<Styles>
<div className="background">
<Container>
<Row id="row" className="justify-content-md-center">
<ExtraInfo />
<SignupForm />
</Row>
</Container>
</div>
</Styles>
);
}
}
export default Signup;
Use Form.Group in React-Bootstrap. It adds 15px padding on columns to separate the content of the columns.
I'm not saying this is the best solution, but I have just created a CSS class that sets a margin attribute to 5px and then applied it to the Row element where I need it. This works for me, but I'm welcome to better answers.
For space at the top and bottom of the screen, what I have done is create a "spacer" component which I import and use to create space between elements.
I know what you mean about messing with the CSS though and this method might be a bit "hacky".
Example JSX:
<>
<p><strong>My Categories</strong></p>
{
catList.map((cat,i) => (
<Row key={i} className="add-space">
<Col><strong>Category {i+1}</strong></Col>
<Col>{cat}</Col>
<Col><Button onClick={() => removeCategory(cat)}>Remove</Button></Col>
</Row>
))
}
</>
Example CSS:
.add-space {
margin: 4px;
}
Example Spacer:
const Spacer = props => {
return (
<div style={{height:props.height}}></div>
);
}
export default Spacer;
Use:
<Spacer height="1rem" />

Why are Styled Component props displaying as HTML attributes?

I'm passing down boolean props to Styled Components to change styling based on the props that are passed into the Component, like so:
<Button href="#contact" small elevate={false} display="primary">
CONTACT
</Button>
The output of this JSX is invalid HTML that looks like this:
<a href="#contact" class="Button__ButtonWrapper-fvVzGy gOcROU" display="primary" fluid="0" elevate="0" small="1">
CONTACT
</a>
Any idea how to ensure props won't be displayed as HTML attrs?
Full Button component:
const ButtonWrapper = styled.button`
padding: ${props =>
props.small
? `${rem(6)} ${props.theme.sizes.sm}`
: `${rem(12)} ${props.theme.sizes.med}`};
box-shadow: ${props =>
props.elevate
? `0 10px 15px 0 rgba(0,0,0,0.10)`
: `0 2px 8px 0 rgba(0,0,0,0.10)`};
color: ${props => {
if (props.display === 'primary') return props.theme.buttons.primary.color;
if (props.display === 'secondary')
return props.theme.buttons.secondary.color;
}};
`;
const Button = ({
display,
fluid,
children,
cta,
elevate,
small,
...other
}) => {
<ButtonWrapper
display={display}
fluid={fluid ? 1 : 0}
elevate={elevate ? 1 : 0}
small={small ? 1 : 0}
{...other}
>
{children}
{cta && (
<div className="icon" dangerouslySetInnerHTML={{ __html: CtaIcon }} />
)}
</ButtonWrapper>
};
export default Button;
This documentation page might be helpful: https://www.styled-components.com/docs/basics#passed-props
Basically if you use a non-camelcase prop to do styling, it'll get passed through to the DOM node. We're looking into better alternatives to this pattern.
I have the exact same problem, when I pass width or height props in to a component they are visible on the html, I think that both words (and maybe others) are actually keywords because with the rest of props this doesn't happen.
Example:
<div class="Container-sc-10mm8fh-0 cyDjRF">
<div class="Line-sc-10mm8fh-1 oPRx"></div>
<div height="3rem" class="VSpace-sc-18gziyv-1 kkKpPd"></div>
<div class="Line-sc-10mm8fh-1 oPRx"></div>
<div height="0.4rem" class="VSpace-sc-18gziyv-1 kkKpPd"></div>
<div class="Line-sc-10mm8fh-1 oPRx"></div>
</div>

How to disable click events for props.children in React?

How can any click events be disabled for props.children?
const Example = props => (
<div>
<div>This can be clicked</div>
{props.children} /* These can't be clicked */
</div>
)
I am rendering a PDF page using react-pdf and want the user to be able to drag a custom selection marquee (like in Photoshop...). As it is, the PDF page under or inside the marquee element still registers mouse events upon dragging, like text selection.
There is an easy, but not robust way to do this:
const Example = props => (
<div style={{pointerEvents:'none'}}>
<div style={{pointerEvents:'auto'}}>This can be clicked</div>
{props.children}
</div>
)
It is not robust, because if any of the children have pointer-events set to auto, they will be clickable too. See if it fits your needs. Also, it will kill hover and other mouse events.
Use CSS Grid to put a div on top!
A transparent div rendered on top of another div will intercept click events.
CSS Grid can be used (abused?) to make a single grid area (using grid-template-areas) and assign multiple elements to it (using grid-area).
JSX
const ClickGuard = ({allow, block}) => (
<div className='click-guard-area'>
<div className='click-guard-allowed'>{props.allow}</div>
<div className='click-guard-block' />
<div className='click-guard-blocked'>{props.block}</div>
</div>
)
CSS
.click-guard-area {
display: grid;
grid-template-areas: 'click-guard';
height: 100%;
width: 100%;
}
.click-guard-allowed {
grid-area: click-guard;
height: 100%;
width: 100%;
z-index: 2;
}
.click-guard-block {
grid-area: click-guard;
height: 100%;
width: 100%;
z-index: 1;
}
.click-guard-blocked {
grid-area: click-guard;
height: 100%;
width: 100%;
}
Note that ClickGuard expects two props: allow and block. These should be JSX. The React docs explain passing React elements here.
<ClickGuard
allow={<div>I can be clicked!</div>}
block={<div>No clicks for me. 😞</div>}
/>
You cannot change the props within an element thus its children props.
An alternative solution may be possible with React.cloneElement,
Here is a simple peace of code for you:
const Example = props => (
<div>
<div>This can be clicked</div>
{props.children.map((child)=>
React.cloneElement(child, {
disabled: true
})
)}
</div>
)

Resources