Avoid repeating code in styled-components - reactjs

I'm using the same styles of components below on two different components in ReactJS. I wanted to know if it is possible to use a kind of mixin storing in another file and export them, then just call them on each ReactJS component? This would avoid repetition of code.
// Repeated styles
const TitleInflow = styled.h1`
text-align: center;
margin-top: 70px;
padding-bottom: 50px;
`;
const Table = styled.table`
margin: 0 auto;
margin-top: 100px;
`;
const ThTable = styled.th`
padding-right: 20px;
padding-left: 20px;
padding-bottom: 10px;
`;

Soluce 1 : You can create a common file like :
Common.js
const Common = `
// style you want.
padding: 5px;
color: red;
`
export default Common
and add it in your styled components like
Components.js
import Common from './common'
const TitleInflow = styled.h1`
${Common};
text-align: center;
margin-top: 70px;
padding-bottom: 50px;
`;
Soluce 2 : You can create a component and extend it :
here a component to extend :
const Component = styled.p`
color: red;
fontSize: 12px;
`
extend style like :
const NewComponent = styled(Component)`
// new style you want.
display: flex;
`
and if you want extend style with an another html tag you can do like it when you will use it :
<NewComponent as="h1"/>

Related

How to test styles files in react-testing library?

I just wanted to know how to test this file using react-testing-library. I am using React Testing Library for first time and it seems very confusing.
import styled from 'styled-components';
export const Salutation = styled.div`
background: #f0f0f0;
font-size: 14px;
padding: 16px;
color: black;
a {
color: blue;
text-decoration: underline;
}
`;
export const Container = styled.div`
padding: 16px;
text-align: center;
`;
export const Header = styled.h3`
font-size: 1.15vw;
font-weight: bold;
padding-bottom: 16px;
`;
export const Label = styled.div`
text-align: left;
font-size: 0.9375vw;
`;
Before you ask the question "how", we need to understand "what" would you want to test in your React component with regard to styling?
One of the goals for writing tests would be to ensure that the UI doesn't change unexpectedly in the future. In that context, you can consider writing Snapshot Tests which involve taking a reference screenshot of the UI and at later points of time, comparing new versions of screenshots to the reference. This also ensures that any changes to the styling haven't been done inadvertently as the test would break.

The 'props' parameter implicitly has a type of 'any'. (Typescript)

I'm adding the dark and light theme effect, and in all containers it worked, but the background color 'props' in this code is not being recognized and returns as "any".
background-color: ${props => props.theme.colors.secondary};
The project is a task list tool and I made the "Type ContainersProps" to validate that the task has been verified. I believe there is conflict here.
import styled from 'styled-components';
type ContainerProps = {
done: boolean;
}
export const Container = styled.div(({ done }: ContainerProps) => (
`
display: flex;
background-color: ${props => props.theme.colors.secondary};
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
align-items: center;
input {
width: 25px;
height: 25px;
margin-right: 5px;
}
label {
color: #000;
text-decoration: ${done ? 'line-through' : 'initial'};
}
`
));
It appears that your issue is that you're mixing two ways of passing props to the styling (you are destructuring done from the props in the function being passed to styled.div() and then you are passing an additional function to be evaluated as the background-color). For custom props, you can look at the Styled-Component docs where you specify your custom type but still use a function to apply it. In your case, that would look like:
type ContainerProps = {
done: boolean;
}
export const Container = styled.div<ContainerProps>`
display: flex;
background-color: ${props => props.theme.colors.secondary};
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
align-items: center;
input {
width: 25px;
height: 25px;
margin-right: 5px;
}
label {
color: #000;
text-decoration: ${props => props.done ? 'line-through' : 'initial'};
}
`;

How to extend a styled component to another component using props?

I'm a benninger learning React with Styled Components.
App.js
const BasicButton = styled.button`
background-color: purple;
`;
Increase.js
const StyledButtonIncrease = styled(props.BasicButton)`
padding: 2rem;
border: none;
border-radius: 7px;
`;
How can I receive a Styled Component in another React component to extend the styling? I tried to use the example above but it didn't work.
What you will actually do is export the styled that you want to extend and import it in the file that you will create your new styled.
ex:
App.js
export const BasicButton = styled.button`
background-color: purple;
`;
increase.js
import { BasicButton } from '../App.js';
const StyledButtonIncrease = styled(BasicButton)`
padding: 2rem;
border: none;
border-radius: 7px;
`;

styled-component dropdown make parent:hover color stay while child:hover

I'm trying to make the parent background color stay changed on hover as I continue to hover over the dropdown items.
https://zqy0v.csb.app/dropdowns < dropdown
import React from "react";
import styled from "styled-components";
//============================================ styles =============================================
const DivDropdownContent = styled.div`
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 24.7rem;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
`;
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
const SpanDropdownTitle = styled.div`
font-size: 1.6rem;
font-weight: bold;
padding: 2rem 6rem;
border-radius: 0.6rem;
border: 1px solid black;
&:hover {
cursor: pointer;
}
`;
const ItemDropdown = styled.p`
padding: 1rem;
&:hover {
cursor: pointer;
background: lightgray;
}
`;
//=========================================== component ===========================================
const BasicDropdown = props => {
return (
<DivDropdown>
<SpanDropdownTitle>Basic Dropdown</SpanDropdownTitle>
<DivDropdownContent>
<ItemDropdown>Item 1</ItemDropdown>
<ItemDropdown>Item 2</ItemDropdown>
<ItemDropdown>Item 3</ItemDropdown>
</DivDropdownContent>
</DivDropdown>
);
};
export default BasicDropdown;
Basically I would like the background color to stay changed for the parent while hovering over the child items in the dropdown, much like is done here https://woocommerce.com/
Is there an easy way to do this, or do I have to start getting complicated with using state and onPointerEnter and onPointerLeave?
I finally ended up finding the solution, and am a bit embarrassed.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Issue: ^This was only targeting the nested component when I added the background cover to the hover.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover {
background: lightgray;
}
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Fix: ^By adding the above, I was able to correct the behavior.
I'm going to leave this question up, because I wasn't able to find much tutorials on this through my internet searching. I think this is a fairly clean solution and think it will help others searching.

How to create Twilio Flex UI themed hml elements

I want to add buttons, form element etc to my component, but they appear without styling. How can I let them render using the theme styling?
Any common componets for buttons/dropdowns/tabs or css classes I can use and how?
I haven't found a good way to actually inherit the styles because they used styled components (Emotion). I've actually been rebuilding flex components (which seems like a waste to be honest).
Here's how I recreated a Flex button:
./src/components/FlexButton/FlexButton.jsx
import React from 'react';
import FlexButtonStyles from './FlexButton.Styles';
const FlexButton = (props) => {
return (
<FlexButtonStyles {...props} />
);
};
export default FlexButton;
./src/component/FlexButton/FlexButton.Styles.js
import { default as styled } from 'react-emotion';
import { withTheme } from '#twilio/flex-ui';
const FlexButtonStyles = styled('button')`
align-self: center;
height: 28px;
font-size: 10px;
font-weight: bold;
letter-spacing: 2px;
white-space: nowrap;
color: rgb(255, 255, 255);
padding: 0px 16px;
border-width: initial;
border-style: none;
border-color: initial;
border-image: initial;
background: linear-gradient(to top, ${props => props.theme.colors.defaultButtonColor}, ${props => props.theme.colors.defaultButtonColor});
outline: none;
border-radius: 100px;
:hover {
background-color: rgba(0, 0, 0, 0.2);
background-blend-mode: color;
}
:disabled{
background: ${props => props.theme.colors.disabledColor};
}
`;
export default withTheme(FlexButtonStyles);
I stole all the CSS by just reviewing the live source code.

Resources