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
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.
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;
`;
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;
`;
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};
}
`;
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} />