How to keep custom attribute in styled component? - styled-components

I created a simple styled component with a custom property test, but when rendered, the test property just did not appear in the div dom, what happened?
const StyledDiv = styled.div<{
test?: boolean;
}>`
color:red;
`;
//in render function...
<StyledDiv test>it's just test</StyledDiv>

In React boolean value is not passed to the dom element in means that test or test={true} will not be available to the dom. It only supports three types of string, number and object and it will convert those to string so all you need to do is change it too test="" and it will work.
If you are looking to access the prop test in your component you need to do something like this:
const StyledDiv = styled.div`
color: ${({test}) => test ? 'red' : 'blue'};
`;

Related

How to change styles of react component using styled components

I have this React component which is a simple button component:
const Button = ({ children }) => <button>{children}</button>;
I tried to pass the above component inside a styled in order to try to change its styles like this:
const StyledButton = styled(Button)`
color: yellow; //does not work
button {
color: yellowgreen; //does not work
}
`;
I am new to styled components so I am not even sure this is possible to do.
Thank you in advance for the help!
When using styled-components for your custom React components, styled-components needs to know where to inject the CSS you want to give to your <button> tag. This is done by passing the className prop to your Button component and passing it as a prop to the <button> tag.
Please try to edit your code like so:
const Button = ({ children, className }) => <button className={className}>{children}</button>;
You can read more about it here Styled Components - Existing CSS.

Extending styled components

I have a Field Formik's component, in order to apply custom CSS I do:
const Input = styled(Field)`
// CSS goes here
`
And use Input component, works fine. However I use exactly the same CSS in many places, so I've extracted those CSS to standalone styled-component called SuperInput
Now, how can extend style-componet? I need something like
const Input = styled(Field)`
// inlucde CSS from SuperInput component here
`
Example code.
import styled from 'styled-components'
const SuperInput = styled.input`
// CSS here
`
import { Field } from 'formik'
import { SuperInput } from 'styled_components/super_input'
const SomeFormComponent = () => (
<>
// How to use here <Field /> that has <SuperInput /> CSS applied?
</>
)
Basically you just need to spread or append inside the template literals to get it to work. you can keep the common CSS something like
import styled, { css } from "styled-components"
const commonCss = css`
background: red;
`
And can use it in your component like this:
const Input = styled(Field)`
// CSS goes here
${commonCss}
color: hotpink;
`;
const Input1 = styled(Field)`
${commonCss}
color: lightblue;
`;
This should allow you to use the common CSS in various styled components.
For more info, you can read through css styled component API
Edit:
Styled components create HOCs.
After the added superInput definition, I understand what you are trying to do. So your superInput is creating a button with the certain css properties which you are trying to reuse. In that case when you are using Field and trying to extend SuperInput which is a button doesnot make sense. Your Field component is by default a input element(text box), it can be checkbox, radio, file input also.Whatever CSS is written in superInput can be extracted the way I mentioned above and used at multiple places. The way you are trying to do is not the way styled component is designed. That's my understanding
Note : I may be wrong here about whether it is possible or not. But that's what i can say according to my awareness . Anyone Feel free to correct me if I am wrong.

Why is theme undefined in styled component props?

Here I access theme by passing a callback function to the styled tag. I guess styled calls this callback function with the props as first argument. This works well.
export default function SectionHeading(props: SectionHeadingProps) {
const Heading = styled.h2`
${props => props.theme.green && `
color: green;
`}
`;
return (
<Heading>{propss.children}</Heading>
);
}
In this example I pass an expression that contains the props the component has received. Here, theme is undefined.
export default function SectionHeading(props: SectionHeadingProps) {
const Heading = styled.h2`
${props.theme.green && `
color: green;
`}
`;
return (
<Heading>{props.children}</Heading>
);
}
Why is theme undefined in the second example?
The reason is that these are different "props" and they are evaluated in different times, in the first example, the props are the props passed to the styled component, augmented with theme (provided you used <ThemeProvider .../>. In the second example, it is the props passed to your component.
The injection of the theme is done by styled-component library and only to styled components. Your component doesn't get it (because it is not a styled component).
Btw, your code has redundant nesting and creates a styled component each time it is invoked.
The way to do it is to simply define:
const SectionHeading = styled.div`
${props => (props.theme && props.theme.green && {color: 'green'})};
`;
and then:
export default SectionHeading;
Note that your sample code has a typo in the first part, you wrote {propss.children} (an extra 's').

How to focus a styled component?

I have a styled component:
const StyledComponent = styled.div`
...
`;
and I want to focus it when the component that uses it is mounted:
class someComponent extends React.Component {
componentDidMount() {
this.sc.focus();
}
render() {
return (
<StyledComponent innerRef={(elem) => { this.sc = elem; }}>
...
</StyledComponent>
);
}
}
this technique does not work - is there a solution for this?
You can't focus non-interactive elements without the use of tabIndex ("tabindex" in normal HTML). The "div" element is considered non-interactive (unlike anchor links "a" and button controls "button".)
If you want to be able to focus this element, you'll need to add a tabIndex prop. You can use .attrs if desired to have it be added automatically so you don't need to write the prop every time.
This link
has an example with both React 16 React.createRef() and the callback method.
Have you tried setting the autoFocus attribute, or is that not fit for your use case?
Try passing the autoFocus prop to your StyledComponent like <StyledComponent autoFocus />.

Sharepoint 2013 JSLink TaskList custom item rendering with out of the box options

I was not able to find the way to customize SP2013 Task List item rendering with JSLink in order to completely change the way that list item is rendered BUT also keeping all out of the box functionalities provided by default.
I mean, I'd like to display list elements as colored boxes, but also keeping sorting options, "..." (Open Menu) icon etc.
How can I achieve it? Is there any documentation where I can find lists of all internal fields like PercentComplete etc. which rendering can be overriden?
Any code snippets would be really appreciated!
Thanks a lot!
Take a look here
In a nutshell, what you want to do is, on the Templates object in the override context object add an object that is called Fields. In this object attributes named the same as the static name of a column(field) are used for rendering the value using the 'View' attribute. So, the example from the link is:
var overrideCtx = {};
overrideCtx.Templates = {};
// Override field data
overrideCtx.Templates.Fields = {
// PercentComplate = internal name of the % Complete
// View = you want to change the field rendering of a view
// <div ... = here we define what the output of the field will be.
'PercentComplete': { 'View' : '<div style="background: #F3F3F3; display:block; height: 20px; width: 100px;"><div style="background: #0072C6; height: 100%; width: <#=ctx.CurrentItem.PercentComplete.replace(" %", "")#>%;"></div></div>' }
};
// Register the override of the field
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx
Using this method you will retain the default functionality in the other fields. Just make sure the column is visible in the current view.

Resources