Styled-components: Interpolated function or component.extend? - css

In styled-component, how do you decide whether you should use interpolated function to modify component ( by passing props ) or extend the existing component. For example:
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// We're extending Button with some extra styles
const TomatoButton = Button.extend`
color: tomato;
border-color: tomato;
`;
render(
<div>
<Button>Normal Button</Button>
<TomatoButton>Tomato Button</TomatoButton>
</div>
);
We could have used interpolated function also. How do you decide between the two?

It different, by passing a props we can use it in other situation but if using extends we just use it as an extra style for a new component something like inherit. Example: for nav menu, if there is an active menu, you dont need to use extends. Just use active class using props.So you dont need to do extend or make new component.

Related

Overwriting styled component 3 times?

I'm using react-bootstrap and styled components on a project and am having issues with extending styles link to docs
For example, im importing and overriding a bootstrap button component:
import styled from 'styled-components';
import Button from 'react-bootstrap/Button';
export const PrimaryButton = styled(Button)`
background-color: ${props => props.theme.purple300};
font-size: 1.25rem;
font-weight: 700;
color: #FFFFFF;
padding: 5px 50px;
border: none;
border-radius: 30px;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3);
`;
this is a good start, however, I want to override this in several locations as well, so something like:
import {Button} from './button.style'
const AuthButton = styled(Button)`
background-color: red;
`;
....
<AuthButton type='submit'>Sign In</AuthButton>
AuthButton should have 3 classes (bootstrap, the first styled component, and then the second), but I'm seeing everything except the AuthButton styles/class. I don't see the background-color: red; anywhere in the DOM. I've tried increasing specificity using &&& and still nothing.
Is this a limitation with styled components or am I doing something wrong?
I fixed this. It was due to not having a className prop in my Button component: https://www.styled-components.com/docs/basics#styling-any-component
EDIT: Since the mods are absolutely horrendous on SO, I will add an example:
function MyComponent({className}) { ... }
you need pass className as a props to your component

Good way to create own button component (Primary button, Secondary button etc.)

I'm new in Angular and I do not even know if this approach is good.
I want to create my own universal button component and define his styles in button.component.css. After i want to use this button in my other component like login form.
I do something like that in button.component.css:
button {
height: 50px;
width: 100px;
border-radius: 8px;
font-family: "Arial Black";
font-size: 18px;
box-shadow: none;
}
.primary-button {
background: #5c52ff;
color: white;
}
.primary-button:hover {
background: white;
border: #5c52ff solid 2px;
color: #5c52ff;
}
.secondary-button {
border: forestgreen solid 2px;
background: white;
color: forestgreen;
}
Now in index.html i do:
<app-button class="primary-button"></app-button>
But scope of button.component.css works only in button.component.html
I should to create this style classes in global style.css and don't create button component but simple use button tag and add class attribute with property from style.css. How to approach this problem.
You should be setting the class to the button present in your button.component.html instead of setting it in the app-button element. You can achieve this by sending your class to the button component as an Input.
index.html
<app-button className="primary-button"></app-button>
button.component.ts
import { Component, Input } from '#angular/core';
....
#Input() className: string;
button.component.html
<button [class]="className"></button>
This way your class will be applied within the scope of button.component.css.

ag-Grid customize tooltip using CSS

I was wondering whether there is a way to customize the built-in tooltip and the header tooltip using CSS? Is there a class name that can be referenced?
Yes, there is a class called ag-tooltip in ag-grid.css
I'm able to customized the default headerTooltip, something like below:
.ag-tooltip{
background-color: #0f1014;
color: #999eab;
border-radius: 2px;
padding: 5px;
border-width: 1px;
border-style: solid;
border-color: #545454;
}
In case you want to customize tooltip using a 3rd party library, you can make use of cell renderer component.
Here is an example using angular cell renderer component and ngx-bootstrap.
#Component({
selector: 'tooltip-cell',
template: `<span tooltip="Custom text" container="body">{{params.value}}</span>`,
})
export class ToolTipRenderer implements ICellRendererAngularComp {
public params: any;
agInit(params: any): void {
this.params = params;
}
refresh(): boolean {
return false;
}
}
Once created, you can register the custom cell renderer component using frameworkComponents gridOption. You can more details in the official doc here
and more details on Cell Renderer Components
I used "Balham" theme in my code and I had to override the default tooltip CSS.
I made a file with the custom CSS.
.ag-theme-balham .ag-tooltip {
background-color: black;
color: white;
border-radius: 2px;
padding: 10px 16px;
border-width: 1px;
border-style: solid;
border-color: #cbd0d3;
transition: opacity 1s;
}
Finally, I imported the CSS file where I had implemented the Ag-Grid.
import "./customTooltipStyle.css";
This worked for me.

target first-child css styled-components

I am using styled-components and want to target the first child of Text, but am unable to do so.
const Text = styled.p`
font-size: 12px;
&:first-child {
margin-bottom: 20px;
}
`;
... component
return(
<div>
<p>I am just regular text</p>
<p>Me too</p>
<Text>Hello Joe</Text> // this should have the margin bottom
<Text>Goodbye</Text >
</div>
)
Finally, I got your issue. The styled component confuses with the first two native p tag (from my perspective) and that's the reason why the CSS is not applied.
I will use a workaround like this:
const Text = styled.p`
font-size: 12px;
color: blue;
&:nth-child(3) {
margin-bottom: 20px;
color: red !important;
}
`;
By doing this, you are selecting the third child (which include the first two p tag) for the CSS
OR, you can do something like this: Adding a class name for the tag and giving CSS for that class.
const Text = styled.p`
font-size: 12px;
color: blue;
&.colors {
margin-bottom: 20px;
color: red !important;
}
`;
<div>
<p>I am just regular text</p>
<p>Me too</p>
<Text className="colors">Hello Joe</Text>
<Text>Goodbye</Text>
</div>
Here is the demo
Hope it helps :)
Use like this
const Text = styled.p`
font-size: 12px;
> * {
&:first-child {
margin-bottom: 20px;
}
}
`;
There shouldn't be a space between the & and the :first-child
&:first-child {
margin-bottom: 20px;
}
it's better to use :last-of-type on certain styled component instead of using :nth-child and it works perfectly
export default styled.div`
:last-of-type {
background: red;
}`
const Text = styled.p`
font-size: 12px;
color: blue;
&:nth-child(3) {
margin-bottom: 20px;
color: red !important;
}
`;
This is possible, but probably not correct
This totally is possible, as we see with the other answers. The issue is that with first-child or nth-child solutions you tend to end up reaching down the DOM hierarchy, creating all sorts of specificity issues that can be difficult to untangle later.
The beauty of Styled Components is you typically apply styles to the element itself, meaning your styles stay tightly coupled to your components. Components become portable, and it's easy to find the line of CSS that might be causing an issue in a complex app.
for example, if I were to style the first <a> in a list item in a ul differently, I'd need to put :first-child further up the hierarchy, breaking encapsulation.
Treat your styles as a function
The simple solution to this is to recognise that the styled component is a function that can receive parameters:
<StyledListItem index={index} />
Then receive that parameter in the component:
export const StyledListItem = styled.li<{index?: number}>`
${
({index}) => {
if (index === 3) return `
color: red;
border: 2px dotted pink;
`
if (index === 0) return `
border-left: none
`
}
}
`
CSS in JS facilitates these kinds of programmatic solutions, and your life will be easier if you leverage them.

React Styled Component space between components

I have several styled components in a row with a image.
I just need to add a space between HeaderLinks.
I've tried following way but it doesn't work.
const HeaderLink = styled.a`
color: #000;
font-size: 1.5em;
`;
const Wrapper = styled.div`
HeaderLink + HeaderLink {
margin-left: 1em;
}
`;
HeaderLink1|HeaderLink2|Image|HeaderLink3|HeaderLink4
So I want to add margin between HeaderLink1&HeaderLink2 and HeaderLink3&HeaderLink4.
How can I use styled component in styled css?
Just used ${HeaderLink} instead of HeaderLink.

Resources