Toggle classes in react styled components with react-responsive library - javascript

I am using react styled components and want to create a toggle functionality or the Link components.
The first step I took was to create the useMediaQueries hook and use min-width and max-width to delimit the pixels.
import { useMediaQuery } from 'react-responsive'
// Media queries
const isDesktop = useMediaQuery({ query: '(min-width: 700px)' });
const isMobile = useMediaQuery({ query: '(max-width: 700px)' });
After this, I created the styled components and moved them into separate file called Header.styles.js:
import { Link } from "react-router-dom";
import styled from "styled-components";
export const LinkStyled = styled(Link)`
text-decoration: none;
color: #333;
margin: 0px 15px 0px 15px;
font-weight: 500;
`;
export const LinkWrapper = styled.div`
display: flex;
flex-wrap: wrap;
`;
export const HeaderWrapper = styled.header`
display: flex;
align-items: center;
justify-content: space-between;
padding: 0px 30px 0px 30px;
/* flex-wrap: wrap; */
`;
The header use the media queries hook and display/hide the menu button and the header wrapper:
// Toggle state
const [ isVisible, setIsvisible ] = useState(false);
return (
<HeaderWrapper>
<p>Expenses</p>
{isDesktop && <LinkWrapper isMobileVersion={isMobile}>
<LinkStyled to='/'>Home</LinkStyled>
<LinkStyled to='/about'>About</LinkStyled>
<LinkStyled to='/profile'>Profile</LinkStyled>
<LinkStyled to='/signup'>Signup</LinkStyled>
<LinkStyled to='/login'>Login</LinkStyled>
</LinkWrapper>}
{ isMobile && <GiHamburgerMenu size={25} onClick={() => setIsvisible(!isVisible)} /> }
</HeaderWrapper>
)
}
I am new to styled components. How can I toggle the classes or assign a class (created in the styled components file) only when the display is set on mobile?
Thanks

I don't see where exactly you wanna use it, but basically you can use ternary operator.
<LinkWrapper style={{ color: isMobile ? "#333" : "#444" }} />
This code is just an example how to solve your problem
Styled components are not just styles, but whole customized components.

Related

Why is my conditional rendering an image for all keys instead of just one in react?

I'm building a tic-tac-toe app. I haven't added functionality between the X's and O's, right now, I'm stuck on rending ONE image via the onClick. I've set the state to make the onClick - at least I think - and I've written out my conditional, but its rendering X images for each square. How do I render an image for only ONE square instead of them all? Here is my code:
Xs.js
import React from 'react'
import styled from 'styled-components'
import X1 from './images/X1.jpg'
import X2 from './images/X2.jpg'
import X3 from './images/X3.jpg'
const Image = styled.img`
width: 175px;
height: 175px;
`
const Xs = () => {
const X = [X1, X2, X3]
const randomXImg = Math.floor(Math.random() * X.length)
return (
<Image src={X[randomXImg]} />
)
}
export default Xs
Cell.js - this is just a div to show for the actual square
import React from 'react'
import styled from 'styled-components'
const CellBlock = styled.div`
display: flex;
align-items: center;
justify-content;
border: 1px solid white;
width: 200px;
height: 200px;
background-color: white;
`
const Container = styled.div`
display: flex;
flex-wrap: nowrap;
flex-direction: column;
align-items: center;
box-sizing: border-box;
`
const Board = styled.div`
display: grid;
grid-template-columns: 210px 210px 202px;
grid-template-rows: 210px 210px 202px;
background-color: darkgreen;
`
const Cell = ({ onClick, isTurn, children }) => {
let squares = []
squares = Array.from(Array(9).fill(''))
return (
<Container>
<Board>
{
squares.map((box, id) => (
<CellBlock
key={id}
id={id}
onClick={onClick}
isTurn={isTurn}
>
{children}
</CellBlock>
))
}
</Board>
</Container>
)
}
export default Cell
Here is the gameboard which is the parent component of both Xs.js and Cell.js
Gameboard.js
import React, { useState } from 'react'
import Cell from './Cell'
import Xs from './Xs'
const Gameboard = () => {
const [ player, setPlayer ] = useState('X')
const [ isNotOccupied, setIsNotOccupied ] = useState(false)
return (
<>
<Cell
onClick={() => setIsNotOccupied(!isNotOccupied)}
isTurn={player}
>
{ isNotOccupied && player === 'X' && <Xs />}
</Cell>
</>
)
}
export default Gameboard
Any help would be greatly appreciated.

How can I remove whitespace from a string in react-native?

I am using react-native. However, when a long string is input, the line breaks are not consistent in the right screen.
like this
However, I would like the string to wrap consistently as in the image below.
this is my code how can i fix or add code??
import React from 'react';
import styled from 'styled-components/native';
const Container = styled.View`
background: lightskyblue;
width: 100%;
height: 100%;
`;
const PolicyContainer = styled.View`
background: lightyellow;
`;
const Label = styled.Text`
font-size: 13px;
`;
const Policy = () => {
return (
<Container>
<PolicyContainer>
<Label>
{'<'}example{'>'}('https://example'이하 'example')은(는) 「개인정보
보호법」 제30조에 따라 정보주체의 개인정보를 보호하고 이와 관련한
고충을 신속하고 원활하게 처리할 수 있도록 하기 위하여 다음과 같이
개인정보 처리방침을 수립·공개합니다.
</Label>
</PolicyContainer>
</Container>
);
};
export default Policy;
Try using text-align: justify; in the style of Label. I believe it will solve your problem.
const Label = styled.Text`
font-size: 13px;
text-align: justify;
`;

How to target a styled component inside another styled component?

Instead of using div:first-child or div:nth-of-type(2) I would like to say Row or
ColSm3 like we usually do in normal CSS,
Is it possible to target a styled component inside another styled component?
or is there is another approach instead of using div:first-child or div:nth-of-type(2)??
Any suggestion?
Normal CSS
.ftrlinkbxs .row{margin: 0 -5px; justify-content: flex-start;}
.ftrlinkbxs .col-sm-3{padding: 0 5px; max-width: 33.33%; flex: 0 0 33.33%; }
HTML
<div class="ftrlinkbxs">
<div class="row">
<div class="col-sm-3">
<strong>Title...</strong>
<ul>
<li>.....</li>
</ul>
</div>
</div>
</div>
Styled Components
export const Ftrlinkbxs = styled.div`
width: 100%;
#media (min-width: 768px){
div:first-child {
margin: 0 1px;
}
div:nth-of-type(2) {
padding: 0 5px;
}
}
`;
export const Row = styled.div`
....
`;
export const ColSm3 = styled.div`
....
`;
You should be able to target a styled component inside a style component like that
const Comp1 = styled.div`
display: flex;
`
// Can be imported from another file
// import Comp1 from './Comp1'
const Comp2 = styled.div`
${Comp1} {
background-color: red;
}
`
Or maybe a better approach would be to pass the component you want as an argument to styled
const Comp1 = styled.div`
display: flex;
`;
// Can be imported from another file
// import Comp1 from './Comp1'
const Comp2 = styled(Comp1)`
background-color: red;
`;

How to redefine a style .tippy-tooltip in "react-tippy"

I want to use "react-tippy" for my project.
How can I override the styles .tippy-tooltip?
Me need to remove padding inside the tooltip.
Here is the Tool tip component I created for my use using react tippy and styled components. You can figure out from there how to customize it to your needs:
Tooltip.js
import React from 'react';
import 'tippy.js/dist/tippy.css';
import { TooltipText, StyledTippy } from './Tooltip.styled';
const Tooltip = ({ moveDown, moveRight, content, ...props }) => (
<StyledTippy
moveDown={moveDown}
moveRight={moveRight}
content={
<TooltipText small bold>
{content}
</TooltipText>
}
placement="bottom"
{...props}
>
{props.children}
</StyledTippy>
);
export default Tooltip;
Tooltip.styled.js
import styled from 'styled-components';
import Tippy from '#tippyjs/react';
export const TooltipText = styled.p`
font-weight: 500;
font-size: 10px;
line-height: 12px;
color: ${({ theme }) => theme.colors.tooltips.simpleText};
`;
export const StyledTippy = styled(Tippy)`
z-index: 5000;
margin-top: ${({ moveDown }) => (moveDown ? `${moveDown}px` : '0')};
margin-left: ${({ moveRight }) => (moveRight ? `${moveRight}px` : '0')};
background: ${({ theme }) => theme.colors.tooltips.simpleBackground};
height: 24px;
width: 110px;
display: flex;
align-items: center;
justify-content: center;
.tippy-arrow {
color: ${({ theme }) => theme.colors.tooltips.simpleBackground};
}
`;

Add styles to Styled Component custom Component in React Native

I have button.js:
import React from "react";
import styled from "styled-components";
const StyledButton = styled.TouchableOpacity`
border: 1px solid #fff;
border-radius: 10px;
padding-horizontal: 10px;
padding-vertical: 5px;
`;
const StyledButtonText = styled.Text`
color: #fff;
font-size: 12;
`;
export default ({ children }) => (
<StyledButton>
<StyledButtonText>{children.toUpperCase()}</StyledButtonText>
</StyledButton>
);
And its usage:
import React, { Component } from "react";
import styled from "styled-components";
import Button from "./button";
const StyledNavView = styled.View`
justify-content: flex-end;
flex-direction: row;
background: #000;
padding-horizontal: 10px;
padding-vertical: 10px;
`;
const StyledTodayButton = styled(Button)`
margin: 10px;
`;
export default class Nav extends Component {
render() {
return (
<StyledNavView>
<StyledTodayButton>Today</StyledTodayButton>
<Button>Previous</Button>
</StyledNavView>
);
}
}
Problem is, the margin I apply in StyledTodayButton is actually never applied. Have I misunderstood extending styles in Styled Components?
There are 2 ways to make it work:
extend button style:
const StyledTodayButton = Button.extend'margin: 10px'
pass prop to button:
const Button = styled.button'
/* ...your props */
margin: ${props => props.withMargin ? '10px' : '0px'};
and then call in render method you can invoke it with:
<Button withMargin {...restProps} />

Categories