Styled component: Nested rules in different files does not work - css

I've defined a file with a styled textarea but I want to use a different piece of style for a React component, at the end I am not able to change the style for the particular tag.
Here below the textarea file
const Container = styled.div`
margin-bottom: 2rem;
`;
const Label = styled(B1)`
margin-bottom: 0.5rem;
`;
const StyledTextArea = styled.textarea`
width: fill-available;
height: 2rem;
padding: 0.25rem;
background-color: black;
font-size: 1rem;
font-weight: 400;
border: none;
border-radius: 0.25rem;
::placeholder {
color: red;
}
`;
const TextArea = ({ label, placeholder, input, rows }) => (
<Container>
{label && <Label>{label}</Label>}
<StyledTextArea rows={rows} {...input} placeholder={placeholder} />
</Container>
);
TextArea.propTypes = {
label: PropTypes.string,
placeholder: PropTypes.string,
input: PropTypes.object.isRequired
};
export default TextArea;
Here below there is my component in which I'd like to change the font-size component but it does not work
const TextBox = styled(TextArea)`
> StyledTextArea {
font-size: 3rem !important;
}
`
class SingleGuestForm extends Component {
<Field
name="Nested Rules"
label="Test with nested rules"
rows="3"
component={TextBox}
/>
}
It seems that the rule defined in the TextBox is ignored by the style engine. Do you know why it happens? I tried different solution (surrounding StyledTextArea with curly braces, etc) but nothing happen even if in the official doc the solution I've implemented should work (here). Thank you so much for any help

Related

Understanding css helper function in styled components

Styled components has a helper css function. But I don't understand when should I used it.
For example this is their example where they use it:
import styled, { css } from 'styled-components'
const complexMixin = css`
color: ${props => (props.whiteColor ? 'white' : 'black')};
`
const StyledComp = styled.div`
/* This is an example of a nested interpolation */
${props => (props.complex ? complexMixin : 'color: blue;')};
`
But if we take similar example from docs here they don't use it:
const Button = styled.button`
/* Adapt the colors based on primary prop */
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
Their description is also not clear and is confusing me:
A helper function to generate CSS from a template literal with
interpolations. You need to use this if you return a template literal
with functions inside an interpolation due to how tagged template
literals work in JavaScript.
Can someone help explain why we need it?
PS this answer also doesn't use it
I use the css function when I create variants for a component:
that is variant switcher:
const sizeVariant: Record<NonNullable<StyledLogoProps['size']>, ReturnType<typeof css>> = {
small: css`
width: 44px;
height: 44px;
`,
regular: css`
width: 93px;
height: 93px;
`,
};
that is component was created by 'styled-components':
interface StyledLogoProps {
size: 'small' | 'regular';
}
export const StyledLogo = styled.div<StyledLogoProps>`
${({ size }) => sizeVariant[size]}
`;
and this is the use in the react:
<>
<StyledLogo size="regular" />
<StyledLogo size="small" />
</>
quite a useful thing

I have tried using styled component in my App. But the cursor moves out after I write city name

In the search area every time I type any letter the cursor moves out and I need to click the text area again to type the next letter. While using CSS it is working fine but in Styled components I am facing the issue. I think there is some issues with my styling but I am unable to debug. How can I fix this issue. Please help.
import React, { FC, useState, FormEvent } from 'react';
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { setAlert } from '../store/actions/alertActions';
import { getWeather, setLoading } from '../store/actions/weatherActions';
interface SearchProps {
title: string;
}
const Search: FC<SearchProps> = ({ title }) => {
const dispatch = useDispatch();
const [city, setCity] = useState('');
const changeHandler = (e: FormEvent<HTMLInputElement>) => {
setCity(e.currentTarget.value);
}
const submitHandler = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if(city.trim() === '') {
return dispatch(setAlert('City is required!'));
}
dispatch(setLoading());
dispatch(getWeather(city));
setCity('');
}
const Header = styled.h1`
font-size: 40px;
font-family: 'sans-serif';
padding-top: 30px;
`;
const Input = styled.input`
font-size: 18px;
padding: 10px;
margin: 10px;
background: #b4e6df;
border: none;
border-radius: 3px;
::placeholder {
color: black;
}
`;
const Button = styled.button`
background-color: #10e2f1;
font-size: 20px;
color: white;
margin: 1em;
border: 3px;
padding: 0.25em 6em;
`;
return(
<>
<Header >{title}
<form onSubmit={submitHandler}>
<Input
type="text"
placeholder="Enter city name"
value={city}
onChange={changeHandler}
/>
<br/>
<Button >Search</Button>
</form>
</Header>
</>
);
}
export default Search;
Looks like the value is changing (or refreshing) whenever you make a change in the input as it is bind with state and also the state is updating on onChange event. Keep independent value instead of state variable in value attribute. something like this:
const defaultValue = ''; // or the default value you are getting from props
const [city, setCity] = useState(defaultValue);
---
---
<Input
type="text"
placeholder="Enter city name"
value={defaultValue}
onChange={changeHandler}
/>
Let me know if it works or not.

react how to style : styled-dropdown-component

I am trying to change the color and the size of the DropdownMenu using the styled-components like the code below:
const DropdownCustom = styled.DropdownMenu`
font-family: sans-serif;
font-size: 1.3rem;
border: none;
border-radius: 5px;
background-color: red;
`;
Then I try to use it like this:
<Dropdown>
<button onClick={() => setState(!state)}>Create</button>
<DropdownCustom hidden={!state}>
<DropdownItem>Action</DropdownItem>
<DropdownItem>Another action</DropdownItem>
<DropdownItem>Something else here</DropdownItem>
</DropdownCustom>
</Dropdown>
But it gives me an error saying that _styledComponents.default.DropdownMenu is not a function.
I am very new to styling with css and it is very confusing, so any advice or guide would be really appreciated! :)
Edited
import {
Dropdown,
DropdownItem,
DropdownMenu
} from "styled-dropdown-component";
If you trying to style a custom component you need to use styled as a function:
const DropdownCustom = styled(DropdownMenu)`
font-family: ...
`;
It will work only if the custom component uses the className props.
Therefore, you sometimes want to style custom component's parent, and target the styling with selectors - as it's just a CSS:
const Wrapper = styled.div`
font-family: ...;
.dropDown {
....;
}
`;
<Wrapper>
<Dropdown />
</Wrapper>

Share the same styles between two types of component with React Styled Components

I would like to apply exactly the same styles to a styled input element and a styled select element.
Currently, I'm using string interpolation to do this:
const styles = `
background-color: white;
width: 100%;
border: 0 solid transparent;
border-radius: 10px;
margin-bottom: 20px;
padding-top: 5px;
padding-bottom: 5px;
font-size: 1.2rem;
`
const Select = styled.select`${styles}`
const Input = styled.input`${styles}`
Is there a better way of doing this which doesn't involve using a 'raw' string? The disadvantage of using the raw styles string is that Visual Studio Code doesn't syntax-highlight it:
You have few options here:
css helper function:
const styles = css`
background-color: white;
// ...
`;
const Select = styled.select`${styles}`;
const Input = styled.input`${styles}`;
"as" polymorphic prop (added in v4):
<Select as="input">
...
</Select>
withComponent method (candidate for deprecation):
const Select = styled.select`
background-color: white;
// ...
`;
const Input = Select.withComponent('input');
You can use the css tagged template literal:
import styled, { css } from "styled-components";
const styles = css`
background-color: white;
width: 100%;
`;
const Select = styled.select`${styles}`;
const Input = styled.input`${styles}`;
That should get properly syntax highlighted (haven't tested).

How to extend(inherit) a global CSS class from within a styled-components

Is it possible to inject a global CSS class into a styled-component?
Similar to extending in LESS using &:extend or #extend in SASS.
This code doesnt apply the globalCSS styles:
const extendedComponent = styled.div`
&:extend(.globalClass) // I want this component to inherit all styles of .globalaCSS
.otherStyles {
...
}
`
The globalClass does exits and even applies styles when used inline:
extendedComponent(className="globalCSS)
you can just add the "class name" to your element,
but if you really want to inherit or extend.
Use their example as reference:
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;
`;
docs link:
https://www.styled-components.com/docs/basics#extending-styles
Use attrs: https://styled-components.com/docs/api#attrs
const extendedComponent = styled.div.attrs({
className: 'globalCssClassThatIWantToExtend'
})`
.otherStyles {
/*...*/
}
`;
The attrs function can also accept a props function:
.attrs(props => ({
/*...*/
}))

Resources